跳到主要内容

动态网站部署

动态网站在用户访问时由服务器实时生成页面内容,可以实现用户注册、内容管理、在线交易等复杂功能。本章将介绍动态网站的架构、部署方法和运维要点。

动态网站架构

基本架构

一个典型的动态网站架构包括以下层次:

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。

手动部署

  1. 安装 LNMP 环境
  2. 下载 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
  1. 创建数据库:
CREATE DATABASE wordpress;
CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON wordpress.* TO 'wordpress'@'localhost';
  1. 配置 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;
}
}
  1. 访问网站完成安装向导

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 服务器、应用服务器、数据库等多个组件的配置和管理。本章介绍了常见运行环境的搭建、容器化部署方法、负载均衡与高可用配置,以及监控日志管理。掌握这些技能,可以部署和维护各种类型的动态网站。

下一章,我们将学习云平台的具体部署操作,了解如何利用云服务商提供的各种服务简化网站部署。