本文约 6000 字,涵盖 Nginx 核心原理、反向代理、负载均衡、HTTPS/HTTP2、限流防刷、缓存加速、Lua 动态扩展、性能调优、Docker 部署及生产踩坑指南,适合有一定 Linux 基础的后端/运维同学。
一、为什么 Nginx 在微服务时代依然不可替代
在 K8s + Spring Cloud Gateway 大行其道的今天,Nginx 依然是很多公司的第一道流量入口。原因很简单:
| 维度 | Nginx | Spring Cloud Gateway |
|---|---|---|
| 性能(10K并发) | ✅ C语言,极低内存 | ⚠️ JVM 预热,内存占用高 |
| 静态资源 | ✅ 原生高效 | ❌ 不擅长 |
| SSL 卸载 | ✅ OpenSSL 原生 | ⚠️ 需额外配置 |
| Lua 扩展 | ✅ OpenResty | ❌ 不支持 |
| 动态路由 | ⚠️ 需 Lua/API | ✅ 代码原生支持 |
| 学习曲线 | 低 | 中(需熟悉 WebFlux) |
结论:Nginx 在接入层(7层入口)做 SSL 卸载、静态资源、限流防刷;Spring Cloud Gateway 在业务层做动态路由、鉴权聚合。两者不是竞争关系,而是黄金搭档。
二、Nginx 核心架构原理(面试必问)
2.1 Master-Worker 进程模型
┌─────────────────────────────────────────┐
│ Master Process │
│ - 读取配置、管理 Worker 生命周期 │
│ - 不处理实际请求 │
└──────────┬──────────────────────────────┘
│ fork
┌──────┴──────┐
▼ ▼
Worker-1 Worker-2 ... (Worker 数 = CPU 核数)
│
├── 连接1 (非阻塞 I/O)
├── 连接2
└── 连接N (单 Worker 可处理数万并发)
- Master:解析配置、绑定端口、管理 Worker(热重载/优雅停机)
- Worker:基于 epoll 的事件驱动模型,单线程处理海量并发
- 热重载原理:
nginx -s reload→ Master 发 USR1 信号 → 新 Worker 用新配置启动 → 旧 Worker 处理完存量请求后退出(零停机)
2.2 epoll 事件驱动 vs 传统 BIO
传统 Apache(BIO):1 请求 = 1 线程,10K 并发 = 10K 线程,内存爆炸
Nginx(epoll):N 请求 = 1 Worker 线程,用 epoll 监听 I/O 就绪事件,内存极低
这就是 Nginx 能用 10MB 内存处理 1 万并发的根本原因。
三、生产级 nginx.conf 完整配置详解
3.1 主配置骨架
# /etc/nginx/nginx.conf
# ============================================================
# 全局配置
# ============================================================
user nginx; # 工作进程用户
worker_processes auto; # 自动等于 CPU 核数
worker_rlimit_nofile 65535; # 单 Worker 最大文件描述符(需同步调整系统 ulimit)
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# ============================================================
# 事件模块
# ============================================================
events {
use epoll; # Linux 下使用 epoll(默认已选最优)
worker_connections 10240; # 单 Worker 最大并发连接数
multi_accept on; # 一次 accept 多个连接(高并发场景打开)
accept_mutex off; # 高并发场景关闭,减少锁竞争
}
# ============================================================
# HTTP 核心模块
# ============================================================
http {
include /etc/nginx/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" "$http_x_forwarded_for" '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time';
log_format json escape=json
'{"time":"$time_iso8601",'
'"client":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"bytes":$body_bytes_sent,'
'"rt":$request_time,'
'"urt":"$upstream_response_time"}';
access_log /var/log/nginx/access.log json; # JSON 格式方便 ELK 解析
# ---------- 传输优化 ----------
sendfile on; # 零拷贝发送文件
tcp_nopush on; # 与 sendfile 配合,减少网络包数量
tcp_nodelay on; # 小包立即发送(长连接场景)
keepalive_timeout 75s; # 客户端长连接超时
keepalive_requests 1000; # 单连接最大请求数
# ---------- 压缩 ----------
gzip on;
gzip_min_length 1024; # 小于 1KB 不压缩
gzip_comp_level 4; # 压缩级别 1-9,4 是性能/压缩率平衡点
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript
image/svg+xml;
gzip_vary on; # 添加 Vary: Accept-Encoding 响应头
gzip_proxied any; # 对代理请求也压缩
# ---------- 缓冲区调优 ----------
client_max_body_size 100m; # 上传文件大小限制
client_body_buffer_size 128k;
proxy_buffer_size 16k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
# ---------- 超时配置 ----------
proxy_connect_timeout 5s; # 连接上游超时
proxy_send_timeout 60s; # 发送请求到上游超时
proxy_read_timeout 60s; # 读取上游响应超时
# ---------- 安全头 ----------
server_tokens off; # 不暴露 Nginx 版本号
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
include /etc/nginx/conf.d/*.conf;
}
四、反向代理与负载均衡
4.1 upstream 负载均衡配置
# /etc/nginx/conf.d/upstream.conf
# ============================================================
# upstream:定义后端服务器组
# ============================================================
# 轮询(默认,适合无状态服务)
upstream backend_rr {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
keepalive 32; # 与上游保持长连接池
}
# 加权轮询(按服务器性能分配流量)
upstream backend_weight {
server 10.0.0.1:8080 weight=5; # 高配机器
server 10.0.0.2:8080 weight=3;
server 10.0.0.3:8080 weight=1 backup; # 备用节点,正常不参与
}
# ip_hash(同一客户端 IP 打到同一后端,适合有状态会话)
upstream backend_iphash {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080 down; # 临时下线(不影响 hash 环)
}
# least_conn(最少连接数,适合请求耗时差异大的场景)
upstream backend_leastconn {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
# hash 一致性哈希(适合缓存穿透场景)
upstream backend_hash {
hash $request_uri consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
4.2 健康检查(商业版 vs 开源方案)
# 开源版:被动健康检查
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
# max_fails=3:3次失败则标记不可用
# fail_timeout=30s:30秒后重新尝试
server 10.0.0.3:8080 max_fails=3 fail_timeout=30s;
}
# 推荐方案:nginx_upstream_check_module(第三方模块)
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "HEAD /actuator/health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
# 暴露健康检查状态页
server {
location /upstream_check {
check_status;
access_log off;
allow 10.0.0.0/8; # 仅内网访问
deny all;
}
}
五、HTTPS + HTTP/2 完整配置
5.1 SSL 证书配置最佳实践
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 92yangyi.top www.92yangyi.top;
# ---------- 证书路径 ----------
ssl_certificate /etc/nginx/ssl/92yangyi.top.pem;
ssl_certificate_key /etc/nginx/ssl/92yangyi.top.key;
# ---------- 协议与加密套件 ----------
ssl_protocols TLSv1.2 TLSv1.3; # 禁用 TLS 1.0/1.1
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off; # TLS 1.3 不需要此选项
# ---------- Session 复用(减少握手开销)----------
ssl_session_cache shared:SSL:20m; # 20MB 共享缓存
ssl_session_timeout 1d;
ssl_session_tickets off; # 禁用 ticket(前向安全)
# ---------- OCSP Stapling(加速证书验证)----------
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# ---------- HSTS(强制 HTTPS,需谨慎开启)----------
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# ---------- HTTP/2 Push(主动推送关键资源)----------
location = /index.html {
http2_push /static/css/main.css;
http2_push /static/js/main.js;
}
# ... 其他 location 配置
}
# HTTP → HTTPS 301 跳转
server {
listen 80;
listen [::]:80;
server_name 92yangyi.top www.92yangyi.top;
return 301 https://$host$request_uri;
}
5.2 Let's Encrypt 自动续签(Certbot + Docker)
# 一键申请证书
docker run --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/www/certbot:/var/www/certbot \
-p 80:80 \
certbot/certbot certonly \
--standalone \
-d 92yangyi.top \
--email admin@92yangyi.top \
--agree-tos \
--no-eff-email
# crontab 每月1日凌晨2点自动续签
0 2 1 * * docker run --rm -v /etc/letsencrypt:/etc/letsencrypt certbot/certbot renew --quiet && nginx -s reload
六、限流与防刷(生产必备)
6.1 请求频率限制(limit_req)
http {
# 定义限流区域:按客户端 IP 限流,10MB 内存约存 16 万条 IP 记录
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
# 按 API Key 限流(更精细,适合 SaaS 场景)
limit_req_zone $http_x_api_key zone=apikey_limit:10m rate=100r/s;
# 登录接口专用限流(严格防爆破)
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
server {
# API 接口:20r/s + 允许突发 50 个请求入队(nodelay 超出立即返回 503)
location /api/ {
limit_req zone=api_limit burst=50 nodelay;
limit_req_status 429; # 返回 429 而非默认 503
# 自定义限流响应
error_page 429 /429.json;
proxy_pass http://backend;
}
# 登录接口:极严格限流
location /api/auth/login {
limit_req zone=login_limit burst=5 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
location = /429.json {
internal;
default_type application/json;
return 429 '{"code":429,"message":"请求过于频繁,请稍后再试"}';
}
}
}
6.2 并发连接限制(limit_conn)
http {
# 按 IP 限制并发连接数
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# 单 IP 最多 20 个并发连接
limit_conn conn_limit 20;
limit_conn_status 503;
# 下载接口限速(防止带宽被单用户耗尽)
location /download/ {
limit_conn conn_limit 5;
limit_rate 500k; # 单连接限速 500KB/s
limit_rate_after 10m; # 前 10MB 不限速(用户体验优先)
proxy_pass http://file_server;
}
}
}
6.3 黑白名单与 Geo 封锁
http {
# IP 黑名单(GeoIP2 模块,需安装 ngx_http_geoip2_module)
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_country_code country iso_code;
}
# 封锁特定国家/地区(按需配置)
map $geoip2_country_code $allowed_country {
default 1;
# CN 1; # 中国大陆
# TW 1; # 台湾
RU 0; # 示例:封锁来自 RU 的请求(仅演示)
}
server {
if ($allowed_country = 0) {
return 403;
}
}
}
# 静态黑名单文件(blocklist.conf)
# deny 192.168.1.100;
# deny 10.0.0.0/8;
# include /etc/nginx/blocklist.conf;
七、静态资源缓存与 CDN 配合
7.1 浏览器缓存策略
server {
# HTML:不缓存(确保用户获取最新页面)
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 带 hash 的静态资源(如 main.abc123.js):长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2|woff|ttf)$ {
expires 365d;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
# 开启 ETag
etag on;
}
# API 响应:禁止缓存
location /api/ {
add_header Cache-Control "no-store";
proxy_pass http://backend;
}
}
7.2 Nginx 代理层缓存(proxy_cache)
http {
# 定义缓存区域(磁盘路径 + 内存索引大小 + 磁盘最大容量)
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=api_cache:50m
max_size=2g
inactive=60m
use_temp_path=off;
server {
# 对 GET 请求开启缓存
location /api/public/ {
proxy_cache api_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 10m; # 200 响应缓存 10 分钟
proxy_cache_valid 404 1m;
proxy_cache_valid any 0; # 其他状态码不缓存
# 缓存 stale 内容(上游宕机时继续服务)
proxy_cache_use_stale error timeout updating
http_500 http_502 http_503 http_504;
# 防止缓存击穿:同一 key 只有一个请求穿透到上游
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
# 响应头中暴露缓存状态(调试用)
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
# 手动清除缓存接口(配合 ngx_cache_purge 模块)
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
proxy_cache_purge api_cache "$scheme$request_method$host$1";
}
}
}
八、OpenResty + Lua:动态扩展能力
当 Nginx 内置指令无法满足复杂业务逻辑时,OpenResty = Nginx + LuaJIT,可以在 Nginx 内嵌入高性能 Lua 脚本。
8.1 安装 OpenResty(Docker 方式)
FROM openresty/openresty:1.25.3.1-alpine
# 安装 Lua 包管理器 opm
RUN opm get ledgetech/lua-resty-http \
&& opm get bungle/lua-resty-redis
COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
COPY lua/ /usr/local/openresty/nginx/lua/
8.2 Lua 实现 Redis 动态黑名单
# nginx.conf(OpenResty)
http {
lua_shared_dict ip_blacklist 10m; # 共享内存缓存黑名单
lua_package_path "/usr/local/openresty/nginx/lua/?.lua;;";
init_worker_by_lua_block {
-- Worker 启动时从 Redis 加载黑名单到共享内存
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379)
if ok then
local ips, _ = red:smembers("nginx:blacklist")
local blacklist = ngx.shared.ip_blacklist
if ips then
for _, ip in ipairs(ips) do
blacklist:set(ip, true, 3600)
end
end
end
}
server {
access_by_lua_block {
local blacklist = ngx.shared.ip_blacklist
local client_ip = ngx.var.remote_addr
if blacklist:get(client_ip) then
ngx.status = 403
ngx.header["Content-Type"] = "application/json"
ngx.say('{"code":403,"message":"您的 IP 已被封禁"}')
return ngx.exit(403)
end
}
location /api/ {
proxy_pass http://backend;
}
# 动态添加黑名单接口
location /admin/blacklist/add {
allow 127.0.0.1;
deny all;
content_by_lua_block {
local args = ngx.req.get_uri_args()
local ip = args.ip
if not ip then
ngx.say('{"code":400,"message":"缺少 ip 参数"}')
return
end
-- 写入共享内存
ngx.shared.ip_blacklist:set(ip, true, 86400)
-- 写入 Redis(持久化)
local redis = require "resty.redis"
local red = redis:new()
red:connect("127.0.0.1", 6379)
red:sadd("nginx:blacklist", ip)
ngx.say('{"code":200,"message":"已加入黑名单"}')
}
}
}
}
8.3 Lua 实现 JWT 鉴权(无需转发到业务服务)
-- /usr/local/openresty/nginx/lua/jwt_auth.lua
local cjson = require "cjson"
local function base64url_decode(str)
str = str:gsub("-", "+"):gsub("_", "/")
local pad = 4 - #str % 4
if pad < 4 then str = str .. string.rep("=", pad) end
return ngx.decode_base64(str)
end
local function verify_jwt(token, secret)
local parts = {}
for part in token:gmatch("[^%.]+") do
table.insert(parts, part)
end
if #parts ~= 3 then return nil, "invalid token format" end
-- 验证签名
local signing_input = parts[1] .. "." .. parts[2]
local sig = ngx.hmac_sha1(secret, signing_input)
local expected = ngx.encode_base64(sig):gsub("+", "-"):gsub("/", "_"):gsub("=", "")
if expected ~= parts[3] then
return nil, "invalid signature"
end
-- 解析 payload
local payload_str = base64url_decode(parts[2])
local payload = cjson.decode(payload_str)
-- 验证过期时间
if payload.exp and payload.exp < ngx.time() then
return nil, "token expired"
end
return payload
end
-- 使用方
local auth_header = ngx.var.http_authorization
if not auth_header or not auth_header:match("^Bearer ") then
ngx.status = 401
ngx.say('{"code":401,"message":"缺少认证 Token"}')
return ngx.exit(401)
end
local token = auth_header:sub(8)
local payload, err = verify_jwt(token, "your-jwt-secret")
if not payload then
ngx.status = 401
ngx.say(cjson.encode({code=401, message=err}))
return ngx.exit(401)
end
-- 将用户信息透传给上游
ngx.req.set_header("X-User-Id", payload.sub)
ngx.req.set_header("X-User-Role", payload.role)
九、Docker Compose 生产部署
9.1 完整部署结构
nginx-stack/
├── docker-compose.yml
├── nginx/
│ ├── nginx.conf
│ ├── conf.d/
│ │ ├── upstream.conf
│ │ └── app.conf
│ └── ssl/
│ ├── cert.pem
│ └── cert.key
├── logs/
└── cache/
9.2 docker-compose.yml
version: "3.9"
services:
nginx:
image: nginx:1.25.4-alpine
container_name: nginx-gateway
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./logs:/var/log/nginx
- ./cache:/var/cache/nginx
networks:
- backend_net
healthcheck:
test: ["CMD", "nginx", "-t"]
interval: 30s
timeout: 10s
retries: 3
# 资源限制
deploy:
resources:
limits:
cpus: "2"
memory: 512M
reservations:
cpus: "0.5"
memory: 128M
# Nginx 日志采集(配合 ELK)
filebeat:
image: elastic/filebeat:8.13.0
container_name: filebeat-nginx
user: root
volumes:
- ./logs:/var/log/nginx:ro
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
networks:
- backend_net
depends_on:
- nginx
networks:
backend_net:
external: true
name: microservice_network
9.3 常用运维命令
# 验证配置语法
docker exec nginx-gateway nginx -t
# 热重载配置(零停机)
docker exec nginx-gateway nginx -s reload
# 查看实时请求日志
docker logs -f nginx-gateway
# 查看 Nginx 运行状态(需开启 stub_status)
curl http://127.0.0.1/nginx_status
# 分析访问日志:Top 10 高频 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 分析响应时间分布(P99 响应时间)
awk '{print $NF}' /var/log/nginx/access.log | sort -n | awk 'BEGIN{c=0}{a[c++]=$1}END{print "P50:", a[int(c*0.5)], "P95:", a[int(c*0.95)], "P99:", a[int(c*0.99)]}'
十、性能调优:从系统到应用
10.1 Linux 内核参数(必须配置)
# /etc/sysctl.conf
# 文件描述符
fs.file-max = 1000000
# TCP 连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1 # 复用 TIME_WAIT 连接
net.ipv4.tcp_fin_timeout = 15 # 缩短 FIN_WAIT2 超时
# TCP 缓冲区
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 应用立即生效
sysctl -p
10.2 Nginx 进程调优
# 绑定 Worker 到特定 CPU(减少上下文切换)
worker_cpu_affinity auto;
# 或手动绑定(4核示例)
# worker_cpu_affinity 0001 0010 0100 1000;
# 优先级(-20 到 19,越小优先级越高)
worker_priority -5;
# Nginx 状态监控(暴露给 Prometheus)
server {
listen 8080;
allow 127.0.0.1;
deny all;
location /nginx_status {
stub_status;
}
location /metrics {
# nginx-prometheus-exporter 会抓取 stub_status 并转换为 Prometheus 格式
proxy_pass http://nginx_exporter:9113/metrics;
}
}
十一、生产踩坑与解决方案
❌ 踩坑一:upstream sent invalid header
现象:代理 Spring Boot 时偶发 502
原因:后端服务返回了格式不规范的 HTTP 响应头
解决:
proxy_pass_header Server;
proxy_pass_header Date;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
❌ 踩坑二:WebSocket 代理断连
现象:WebSocket 连接一段时间后自动断开
解决:
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s; # WebSocket 长连接,延长超时
proxy_send_timeout 3600s;
}
❌ 踩坑三:大文件上传 413 错误
现象:上传超过 1MB 的文件时返回 413 Request Entity Too Large
解决:
client_max_body_size 500m; # 全局或 location 内配置
client_body_timeout 300s; # 上传超时(慢速网络)
proxy_request_buffering off; # 大文件不缓存到 Nginx,直接流式转发
❌ 踩坑四:CORS 重复响应头
现象:前端报 The 'Access-Control-Allow-Origin' header contains multiple values
原因:Nginx 和后端服务都添加了 CORS 头
解决:
location /api/ {
# 先删除上游返回的 CORS 头,再由 Nginx 统一添加
proxy_hide_header Access-Control-Allow-Origin;
proxy_hide_header Access-Control-Allow-Methods;
add_header Access-Control-Allow-Origin $http_origin always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Allow-Credentials "true" always;
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://backend;
}
❌ 踩坑五:no live upstreams while connecting to upstream
现象:所有后端都宕机时 Nginx 返回 502
解决:配置自定义错误页 + 备用上游
upstream backend {
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:9999 backup; # 备用:本地静态维护页服务
}
error_page 502 503 504 /maintenance.html;
location = /maintenance.html {
root /var/www/html;
internal;
}
十二、完整架构图:Nginx 在微服务体系中的位置
Internet
│
▼
┌──────────────────────────────────────┐
│ CDN(Cloudflare / 阿里云 CDN) │
│ 静态资源缓存、DDoS 防护、边缘加速 │
└──────────────────┬───────────────────┘
│ HTTPS
▼
┌──────────────────────────────────────┐
│ Nginx(接入层网关) │
│ ✅ SSL 卸载(TLS 1.3 + HTTP/2) │
│ ✅ 限流防刷(limit_req / limit_conn) │
│ ✅ 黑名单(Lua + Redis 动态更新) │
│ ✅ 静态资源服务 & 代理缓存 │
│ ✅ 负载均衡(upstream 健康检查) │
│ ✅ CORS 统一处理 │
│ ✅ 日志采集(JSON → Filebeat → ELK) │
└──────────────────┬───────────────────┘
│ HTTP(内网)
▼
┌──────────────────────────────────────┐
│ Spring Cloud Gateway(业务层) │
│ ✅ JWT 鉴权 & 权限验证 │
│ ✅ 动态路由(Nacos) │
│ ✅ 接口聚合 & 协议转换 │
│ ✅ 服务限流(Sentinel) │
└──────────┬───────────────┬───────────┘
│ │
▼ ▼
微服务集群 微服务集群
(Spring Boot) (Spring Boot)
┌──────────┐ ┌──────────┐
│ 订单服务 │ │ 用户服务 │ ...
└──────────┘ └──────────┘
十三、总结
本文从 Nginx 的 Master-Worker 架构和 epoll 原理出发,系统梳理了生产环境中 Nginx 的核心使用场景:
| 能力 | 配置要点 |
|---|---|
| 反向代理 & 负载均衡 | upstream + 健康检查 + 长连接池 |
| HTTPS / HTTP2 | TLS 1.3 + OCSP Stapling + Session 复用 |
| 限流防刷 | limit_req_zone + burst + nodelay |
| 代理缓存 | proxy_cache + cache_lock + stale |
| 动态扩展 | OpenResty + Lua(JWT鉴权、动态黑名单) |
| 性能调优 | 内核参数 + CPU 绑定 + gzip + sendfile |
| 生产运维 | Docker Compose + 热重载 + 日志分析 |
Nginx 的价值在于它的极致性能和可编程性。在微服务架构中,它是不可替代的第一道防线,与 Spring Cloud Gateway 协同分工,共同构建高可用、高安全的流量入口体系。
参考资料
- Nginx 官方文档:https://nginx.org/en/docs/
- OpenResty 文档:https://openresty.org/en/
- Mozilla SSL 配置生成器:https://ssl-config.mozilla.org/
- Nginx 性能调优 Wiki:https://www.nginx.com/resources/wiki/
评论区