第 5 章:Nginx 原理与配置 Nginx 是全球使用最广泛的 Web 服务器和反向代理。理解 Nginx 是生产环境部署的必备技能。
5.1 Nginx 是什么? Nginx(发音 "engine-x")是由 Igor Sysoev 于 2004 年创建的 高性能 HTTP 服务器和反向代理服务器 。
全球使用率 ┌─────────────────────────────────────────────┐
│ 全球 Web 服务器市场份额 │
│ │
│ Nginx ████████████████████████████ 34% │
│ Apache ████████████████ 20% │
│ Cloudflare ██████████████ 14% │
│ Caddy ████ 4% │
│ 其他 ████████████████████ 28% │
└─────────────────────────────────────────────┘
Nginx 能做什么? 功能 说明 反向代理 接收客户端请求,转发给后端服务器 负载均衡 将请求分发到多个后端实例 静态文件服务 高效提供 HTML/CSS/JS/图片 SSL/TLS 终止 处理 HTTPS 加密/解密 缓存 缓存后端响应,减轻后端压力 限流 控制请求频率,防止滥用 WebSocket 代理 WebSocket 连接 gRPC 代理 代理 gRPC 服务
5.2 为什么需要 Nginx? 问题:直接暴露应用服务器 客户端 ──────────────────→ Express/FastAPI
│
│ 问题:
│ ❌ 无法处理 HTTPS
│ ❌ 无法负载均衡
│ ❌ 静态文件效率低
│ ❌ 无法限流
│ ❌ 单点故障
│ ❌ 无法缓存
方案:Nginx 作为前置层 客户端 ──→ Nginx ──→ Express 实例 1
├─→ Express 实例 2
├─→ Express 实例 3
└─→ FastAPI 实例
✅ HTTPS 在 Nginx 配置
✅ 负载均衡自动分发
✅ 静态文件 Nginx 直接返回
✅ 限流/防火墙在 Nginx 层
✅ 多实例高可用
✅ 响应缓存
5.3 Nginx 架构与事件模型 进程模型 ┌──────────────────────────────────────────────┐
│ Nginx Master 进程 │
│ (管理 Worker 进程,加载配置) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Worker 1 │ │ Worker 2 │ │ Worker N │ │
│ │ (事件驱动)│ │ (事件驱动)│ │ (事件驱动)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ └────────────┴────────────┘ │
│ 共享端口(accept_mutex) │
└──────────────────────────────────────────────┘
Master 进程 :读取配置、管理 Worker 进程、平滑重启 Worker 进程 :实际处理请求,数量通常等于 CPU 核心数 事件驱动 vs 多线程 Apache(多线程/多进程):
10000 个并发连接 → 10000 个线程 → 💥 内存耗尽
Nginx(事件驱动):
10000 个并发连接 → 4 个 Worker 进程 → ✅ 每个 Worker 用 epoll 处理 2500 个连接
epoll/kqueue 原理 Linux 使用 epoll,macOS/BSD 使用 kqueue
传统方式(select/poll):
for each connection:
check if has data ← 每次都要遍历所有连接
时间复杂度:O(n)
epoll 方式:
操作系统主动通知哪些连接有数据 ← 只处理有数据的连接
时间复杂度:O(1)
5.4 配置文件结构 配置文件位置 # 主配置文件
/etc/nginx/nginx.conf
# 站点配置
/etc/nginx/conf.d/*.conf
# 或
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
配置层次 # nginx.conf 结构
worker_processes auto ; # 全局配置
events { # 事件配置
worker_connections 1024 ;
}
http { # HTTP 配置
include mime.types ;
default_type application/octet-stream ;
# 日志格式
log_format main ' $remote_addr - $remote_user [ $time_local] '
'" $request" $status $body_bytes_sent '
'" $http_referer" " $http_user_agent"' ;
access_log /var/log/nginx/access.log main ;
# 性能优化
sendfile on ;
tcp_nopush on ;
keepalive_timeout 65 ;
gzip on ;
# 上游服务器(负载均衡)
upstream backend {
server 127.0.0.1 : 3000 ;
server 127.0.0.1 : 3001 ;
server 127.0.0.1 : 3002 ;
}
# 虚拟主机(Server Block)
server {
listen 80 ;
server_name example.com ;
# 路由(Location Block)
location / {
root /var/www/html ;
index index.html ;
}
location /api/ {
proxy_pass http://backend ;
}
}
}
5.5 反向代理配置 基本反向代理 server {
listen 80 ;
server_name api.example.com ;
location / {
proxy_pass http://127.0.0.1:3000 ;
# 传递原始请求信息
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 ;
# 超时设置
proxy_connect_timeout 60s ;
proxy_send_timeout 60s ;
proxy_read_timeout 60s ;
}
}
多应用路由 server {
listen 80 ;
server_name example.com ;
# Express 应用
location /api/ {
proxy_pass http://127.0.0.1:3000 ;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
}
# FastAPI 应用
location /ai/ {
proxy_pass http://127.0.0.1:8000 ;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
}
# 静态网站
location / {
root /var/www/frontend ;
index index.html ;
try_files $uri $uri/ /index.html ; # SPA 支持
}
}
WebSocket 代理 location /ws/ {
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 ;
}
5.6 负载均衡 负载均衡策略 # 1. 轮询(Round Robin,默认)
upstream backend {
server 127.0.0.1 : 3000 ;
server 127.0.0.1 : 3001 ;
server 127.0.0.1 : 3002 ;
}
# 2. 加权轮询
upstream backend {
server 127.0.0.1 : 3000 weight=3 ; # 接收 3/6 的请求
server 127.0.0.1 : 3001 weight=2 ; # 接收 2/6 的请求
server 127.0.0.1 : 3002 weight=1 ; # 接收 1/6 的请求
}
# 3. IP Hash(同一 IP 始终到同一后端)
upstream backend {
ip_hash ;
server 127.0.0.1 : 3000 ;
server 127.0.0.1 : 3001 ;
server 127.0.0.1 : 3002 ;
}
# 4. 最少连接
upstream backend {
least_conn ;
server 127.0.0.1 : 3000 ;
server 127.0.0.1 : 3001 ;
server 127.0.0.1 : 3002 ;
}
健康检查 upstream backend {
server 127.0.0.1 : 3000 max_fails=3 fail_timeout=30s ;
server 127.0.0.1 : 3001 max_fails=3 fail_timeout=30s ;
server 127.0.0.1 : 3002 backup ; # 备用服务器,其他都挂了才用
}
5.7 SSL/TLS 配置 HTTPS 配置 server {
listen 443 ssl http2 ;
server_name example.com ;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem ;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem ;
# SSL 优化
ssl_protocols TLSv1.2 TLSv1.3 ;
ssl_ciphers HIGH:!aNULL:!MD5 ;
ssl_prefer_server_ciphers on ;
ssl_session_cache shared:SSL:10m ;
ssl_session_timeout 10m ;
location / {
proxy_pass http://backend ;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr ;
proxy_set_header X-Forwarded-Proto $scheme ;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80 ;
server_name example.com ;
return 301 https:// $server_name$request_uri ;
}
Let's Encrypt 免费证书 # 安装 certbot
sudo apt install certbot python3-certbot-nginx
# 自动获取并配置证书
sudo certbot --nginx -d example.com
# 自动续期(certbot 会添加 cron)
sudo certbot renew --dry-run
5.8 静态文件优化 基本静态文件服务 server {
listen 80 ;
server_name static.example.com ;
root /var/www/static ;
# HTML/JS/CSS 缓存 1 年
location ~ * \.(html|css|js) $ {
expires 1y ;
add_header Cache-Control "public, immutable" ;
}
# 图片缓存 1 年
location ~ * \.(jpg|jpeg|png|gif|ico|svg|webp) $ {
expires 1y ;
add_header Cache-Control "public, immutable" ;
}
# 字体缓存 1 年
location ~ * \.(woff|woff2|ttf|eot) $ {
expires 1y ;
add_header Cache-Control "public, immutable" ;
}
# 其他文件不缓存
location / {
add_header Cache-Control "no-cache" ;
}
}
Gzip 压缩 gzip on ;
gzip_vary on ;
gzip_proxied any ;
gzip_comp_level 6 ; # 压缩级别 1-9,6 是性价比最好的
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/rss+xml
image/svg+xml ;
压缩效果示例:
原始 JS 文件:500KB
Gzip 压缩后:150KB ← 节省 70% 带宽
压缩耗时:< 1ms ← CPU 开销极小
5.9 限流配置 基本限流 # 定义限流区域
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s ;
# 10m 内存,每秒 10 个请求 per IP
server {
location /api/ {
limit_req zone=api burst=20 nodelay ;
# burst=20:允许突发 20 个请求
# nodelay:突发请求不延迟,直接处理
proxy_pass http://backend ;
}
}
多级限流 # 全局限流
limit_req_zone $binary_remote_addr zone=global:10m rate=100r/s ;
# API 限流(更严格)
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s ;
# 登录限流(最严格)
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s ;
server {
location / {
limit_req zone=global burst=50 nodelay ;
}
location /api/ {
limit_req zone=api burst=20 ;
proxy_pass http://backend ;
}
location /api/auth/login {
limit_req zone=login burst=3 nodelay ;
proxy_pass http://backend ;
}
}
5.10 缓存配置 反向代理缓存 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m
max_size=1g inactive=60m use_temp_path=off ;
server {
location /api/products {
proxy_cache api_cache ;
proxy_cache_valid 200 10m ; # 200 响应缓存 10 分钟
proxy_cache_valid 404 1m ; # 404 响应缓存 1 分钟
proxy_cache_use_stale error timeout updating ;
# 添加缓存命中头
add_header X-Cache-Status $upstream_cache_status ;
proxy_pass http://backend ;
}
}
响应头:
X-Cache-Status: HIT ← 缓存命中
X-Cache-Status: MISS ← 缓存未命中
X-Cache-Status: EXPIRED ← 缓存过期
5.11 安全配置 安全头 add_header X-Frame-Options "SAMEORIGIN" always ;
add_header X-Content-Type-Options "nosniff" always ;
add_header X-XSS-Protection "1 ; mode=block" always ;
add_header Referrer-Policy "strict-origin-when-cross-origin" always ;
add_header Content-Security-Policy "default-src 'self'" always ;
add_header Strict-Transport-Security "max-age=31536000 ; includeSubDomains" always ;
# 隐藏版本号
server_tokens off ;
IP 黑白名单 # 白名单
location /admin/ {
allow 192 .168.1.0/24 ;
allow 10 .0.0.0/8 ;
deny all ;
proxy_pass http://backend ;
}
# 黑名单
location / {
deny 192 .168.1.100 ;
proxy_pass http://backend ;
}
5.12 性能调优 nginx.conf 优化 worker_processes auto ; # 等于 CPU 核心数
worker_rlimit_nofile 65535 ; # 文件描述符限制
events {
worker_connections 4096 ; # 每个 Worker 的最大连接数
multi_accept on ; # 一次性接受多个连接
use epoll ; # Linux 使用 epoll
}
http {
sendfile on ; # 零拷贝传输
tcp_nopush on ; # 与 sendfile 配合
tcp_nodelay on ; # 禁用 Nagle 算法
keepalive_timeout 65 ;
keepalive_requests 1000 ; # 单个连接最多处理 1000 个请求
client_max_body_size 50m ; # 最大请求体
client_body_buffer_size 128k ;
# 缓冲区优化
proxy_buffer_size 128k ;
proxy_buffers 4 256k ;
proxy_busy_buffers_size 256k ;
include /etc/nginx/conf.d/*.conf ;
}
理论并发连接数:
worker_processes × worker_connections = 4 × 4096 = 16384
5.13 日志分析 访问日志格式 log_format detailed ' $remote_addr - $remote_user [ $time_local] '
'" $request" $status $body_bytes_sent '
'" $http_referer" " $http_user_agent" '
'rt= $request_time uct=" $upstream_connect_time" '
'uht=" $upstream_header_time" urt=" $upstream_response_time"' ;
常用分析命令 # 统计每个 IP 的请求数
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 找出最慢的请求(> 5s)
awk '$NF > 5' /var/log/nginx/access.log
# 统计 API 调用次数
grep '/api/' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
5.14 常用命令 # 测试配置
nginx -t
# 重新加载配置(不中断服务)
nginx -s reload
# 重启
systemctl restart nginx
# 查看状态
systemctl status nginx
# 查看错误日志
tail -f /var/log/nginx/error.log
# 日志轮转
logrotate -f /etc/logrotate.d/nginx
5.15 总结 核心概念 一句话 事件驱动 epoll/kqueue 实现高并发,不依赖多线程 Master-Worker Master 管理配置,Worker 处理请求 反向代理 接收请求并转发,隐藏后端服务器 负载均衡 轮询/加权/IP Hash/最少连接 SSL 终止 HTTPS 在 Nginx 层处理,后端用 HTTP 缓存 减少后端压力,提升响应速度 限流 防止 API 滥用和 DDoS 攻击
Nginx 是生产环境的标配。 无论是个人项目还是大厂,Nginx 都是第一道防线。
上一章:FastAPI 框架 | 下一章:完整架构实战