动态网站部署
动态网站在用户访问时由服务器实时生成页面内容,可以实现用户注册、内容管理、在线交易等复杂功能。本章将介绍动态网站的架构、部署方法和运维要点。
动态网站架构
基本架构
一个典型的动态网站架构包括以下层次:
Web 服务器层
负责接收 HTTP 请求,返回响应内容。常用软件有 Nginx、Apache。Web 服务器通常作为反向代理,将动态请求转发给应用服务器。
应用服务器层
执行业务逻辑,处理动态请求。根据技术栈不同,可以是 PHP-FPM、Tomcat、Gunicorn、Node.js 等。
数据库层
存储和管理数据。常用数据库有 MySQL、PostgreSQL、MongoDB 等。
缓存层
缓存热点数据,减轻数据库压力。常用 Redis、Memcached。
文件存储层
存储用户上传的文件、图片等。可以使用本地存储或对象存储服务。
架构示例
用户请求
│
▼
┌─────────────┐
│ Nginx │ 负载均衡、反向代理、静态资源服务
└─────────────┘
│
▼
┌─────────────┐
│ 应用服务器 │ PHP-FPM / Gunicorn / Node.js
└─────────────┘
│
├──────────────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ MySQL │ │ Redis │
└─────────┘ └─────────┘
应用运行环境
PHP 环境
LNMP 架构:Linux + Nginx + MySQL + PHP
安装 PHP 和 PHP-FPM:
# Ubuntu/Debian
apt install -y php php-fpm php-mysql php-gd php-xml php-mbstring
# CentOS/RHEL
yum install -y php php-fpm php-mysqlnd php-gd php-xml php-mbstring
配置 Nginx 与 PHP-FPM:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Python 环境
常用框架:Django、Flask、FastAPI
安装 Python 和虚拟环境:
apt install -y python3 python3-pip python3-venv
创建虚拟环境并安装依赖:
python3 -m venv /var/www/myapp/venv
source /var/www/myapp/venv/bin/activate
pip install gunicorn django
使用 Gunicorn 运行 Django:
gunicorn --bind 127.0.0.1:8000 myproject.wsgi:application
配置 Systemd 服务:
# /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn daemon for myproject
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/venv/bin/gunicorn \
--workers 3 \
--bind 127.0.0.1:8000 \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Nginx 配置:
server {
listen 80;
server_name example.com;
location /static/ {
alias /var/www/myapp/static/;
}
location /media/ {
alias /var/www/myapp/media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Node.js 环境
安装 Node.js:
# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
apt install -y nodejs
# CentOS/RHEL
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs
使用 PM2 管理 Node.js 进程:
npm install -g pm2
pm2 start app.js --name myapp
pm2 startup
pm2 save
Nginx 反向代理:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Java 环境
安装 JDK:
# Ubuntu/Debian
apt install -y openjdk-17-jdk
# CentOS/RHEL
yum install -y java-17-openjdk-devel
运行 Spring Boot 应用:
java -jar myapp.jar
配置 Systemd 服务:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot Application
After=network.target
[Service]
Type=simple
User=appuser
ExecStart=/usr/bin/java -jar /var/www/myapp/myapp.jar
Restart=on-failure
[Install]
WantedBy=multi-user.target
数据库配置
MySQL 安装与配置
安装 MySQL:
# Ubuntu/Debian
apt install -y mysql-server
# CentOS/RHEL
yum install -y mysql-server
安全配置:
mysql_secure_installation
创建数据库和用户:
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON myapp.* TO 'myapp'@'localhost';
FLUSH PRIVILEGES;
Redis 安装与配置
安装 Redis:
apt install -y redis-server
配置 Redis:
# /etc/redis/redis.conf
bind 127.0.0.1
requirepass your_redis_password
maxmemory 256mb
maxmemory-policy allkeys-lru
启动 Redis:
systemctl restart redis
systemctl enable redis
容器化部署
Docker 可以简化应用的部署和管理,确保环境一致性。
Dockerfile 示例
Python 应用:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "myproject.wsgi:application"]
Node.js 应用:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Docker Compose
使用 Docker Compose 编排多个服务:
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://user:password@db:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
volumes:
- static:/app/static
- media:/app/media
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- static:/var/www/static:ro
- media:/var/www/media:ro
depends_on:
- web
volumes:
postgres_data:
redis_data:
static:
media:
启动服务:
docker-compose up -d
常见应用部署
WordPress 部署
WordPress 是最流行的内容管理系统,基于 PHP 和 MySQL。
手动部署:
- 安装 LNMP 环境
- 下载 WordPress:
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
mv wordpress /var/www/html/
chown -R www-data:www-data /var/www/html/wordpress
- 创建数据库:
CREATE DATABASE wordpress;
CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON wordpress.* TO 'wordpress'@'localhost';
- 配置 Nginx:
server {
listen 80;
server_name example.com;
root /var/www/html/wordpress;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- 访问网站完成安装向导
Docker 部署:
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "80:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: password
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db_data:/var/lib/mysql
volumes:
wordpress_data:
db_data:
Django 应用部署
准备项目:
# 克隆代码
git clone https://github.com/yourname/myproject.git
cd myproject
# 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
pip install gunicorn
# 收集静态文件
python manage.py collectstatic
# 数据库迁移
python manage.py migrate
Gunicorn 配置:
# gunicorn.conf.py
bind = "127.0.0.1:8000"
workers = 4
threads = 2
Nginx 配置:
server {
listen 80;
server_name example.com;
location /static/ {
alias /var/www/myproject/static/;
}
location /media/ {
alias /var/www/myproject/media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
负载均衡与高可用
Nginx 负载均衡
upstream backend {
server 192.168.1.10:8000 weight=3;
server 192.168.1.11:8000 weight=2;
server 192.168.1.12:8000 backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
负载均衡策略:
- 轮询(默认):按顺序分配请求
- 权重(weight):按权重比例分配
- IP 哈希(ip_hash):同一 IP 分配到同一服务器
- 最少连接(least_conn):分配到连接数最少的服务器
数据库主从复制
MySQL 主从复制配置:
主库配置:
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
创建复制用户:
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
从库配置:
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 2
relay_log = mysql-relay-bin
read_only = 1
配置复制:
CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
START SLAVE;
监控与日志
应用监控
Prometheus + Grafana:
安装 Prometheus:
# docker-compose.yml
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
日志管理
Nginx 日志格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
日志轮转:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
小结
动态网站部署涉及 Web 服务器、应用服务器、数据库等多个组件的配置和管理。本章介绍了常见运行环境的搭建、容器化部署方法、负载均衡与高可用配置,以及监控日志管理。掌握这些技能,可以部署和维护各种类型的动态网站。
下一章,我们将学习云平台的具体部署操作,了解如何利用云服务商提供的各种服务简化网站部署。