4303 字
22 分钟
Nginx 进阶实战完全指南:负载均衡策略 + 限流模块 + 缓存加速 + WebSocket + SSL 双向认证
掌握 Nginx 基础反代配置之后,如何让它在真实生产环境中稳定、高效、安全地运行,才是工程化落地的核心挑战。本文聚焦 Nginx 进阶实战,系统讲解五大生产级主题:
- 负载均衡进阶:四种策略深度对比 + upstream 健康检查 + 故障摘除
- 限流防护:
limit_req(QPS 限制)+limit_conn(并发限制)+ 分级限流 - 缓存加速:
proxy_cache完整配置 + 缓存失效策略 + 命中率调优 - WebSocket 穿透:长连接配置 + 心跳保活 + 断线重连处理
- SSL 双向认证(mTLS):客户端证书验证原理与生产配置
📖 前置阅读:本文是 Nginx 反向代理配置实战完全指南 的进阶延续,建议先掌握
proxy_pass、upstream基础后再阅读本文。
一、负载均衡进阶
1.1 四种内置策略深度对比
Nginx 开源版内置四种负载均衡策略,选错策略会导致性能瓶颈或状态丢失:
| 策略 | 配置关键字 | 算法 | 适用场景 | 局限性 |
|---|---|---|---|---|
| 轮询(默认) | 无需关键字 | 依次循环 | 无状态、同质后端 | 不考虑后端实际负载 |
| 加权轮询 | weight=N | 按权重分配 | 后端性能差异大 | 不考虑实时负载 |
| IP Hash | ip_hash | 客户端 IP 哈希 | 有 Session 的有状态服务 | IP 变动导致 Session 失效 |
| 最少连接 | least_conn | 优先最少连接后端 | 长连接/响应时间差异大 | 连接数≠实际负载 |
生产选型建议:
无状态 REST API → round-robin 或 least_conn(推荐 least_conn)用户登录/购物车 → ip_hash(保持 Session 一致性)数据库代理/长连接服务 → least_conn静态资源 CDN 源站 → round-robin(配合 keepalive)混合场景(推荐方案) → least_conn(通用性最好)1.2 完整 upstream 配置模板
http { # ── 基础轮询 upstream ────────────────────────────── upstream backend_rr { server 10.0.0.1:8080; server 10.0.0.2:8080; server 10.0.0.3:8080; # 保持与后端的长连接池,避免频繁 TCP 握手 keepalive 32; }
# ── 加权轮询:按服务器性能分配流量 ──────────────── upstream backend_weighted { server 10.0.0.1:8080 weight=5; # 承担 50% 流量 server 10.0.0.2:8080 weight=3; # 承担 30% 流量 server 10.0.0.3:8080 weight=2; # 承担 20% 流量 keepalive 16; }
# ── IP Hash:有状态服务 Session 保持 ────────────── upstream backend_session { ip_hash; server 10.0.0.1:8080; server 10.0.0.2:8080; # 临时下线(不删除,保留 hash 槽位) server 10.0.0.3:8080 down; keepalive 16; }
# ── 最少连接:动态负载均衡(推荐生产默认)───────── upstream backend_leastconn { least_conn; 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 10.0.0.3:8080 backup; keepalive 32; }}1.3 后端健康检查与故障自动摘除
Nginx 开源版通过被动健康检查实现故障摘除:
upstream backend { least_conn;
# max_fails:在 fail_timeout 时间窗口内,连续失败 N 次则标记为不可用 # fail_timeout:判定失败的时间窗口(同时也是摘除后的冷却时间) 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 10.0.0.3:8080 max_fails=3 fail_timeout=30s backup;
keepalive 32; # HTTP/1.1 长连接(必须配合 keepalive) keepalive_requests 1000; keepalive_timeout 60s;}
server { location /api/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; # 清除 Connection 头,启用长连接
# 失败重试:遇到错误/超时自动切换到下一台后端 proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; # 最多重试 3 次 proxy_next_upstream_timeout 10s; # 重试总超时
proxy_connect_timeout 5s; proxy_send_timeout 30s; proxy_read_timeout 30s; }}参数说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
max_fails | 触发摘除的失败次数 | 3(过小会误摘) |
fail_timeout | 判定窗口 & 冷却时间 | 30s |
backup | 备用节点,主节点全挂才启用 | 至少配一个 |
proxy_next_upstream | 遇到哪些错误触发重试 | error timeout http_502 http_503 |
1.4 upstream 状态监控(stub_status)
server { listen 8080; # 仅允许本机访问,不要对外暴露 allow 127.0.0.1; deny all;
location /nginx_status { stub_status; }}访问 http://127.0.0.1:8080/nginx_status 可看到:
Active connections: 291server accepts handled requests 16630948 16630948 31070465Reading: 6 Writing: 179 Waiting: 106二、限流防护:limit_req + limit_conn
限流是防止 CC 攻击、接口滥用、爬虫刷量的核心手段。Nginx 提供两个互补的限流模块:
| 模块 | 限制维度 | 算法 | 防护目标 |
|---|---|---|---|
limit_req | 请求速率(QPS) | 漏桶算法 | 接口刷量、CC 攻击 |
limit_conn | 并发连接数 | 计数器 | 连接池耗尽、慢速攻击 |
2.1 limit_req:QPS 限流
基础配置
http { # 定义共享内存区:存储每个 IP 的请求计数 # zone=req_limit:10m → 10MB 内存区,约可存储 160,000 个 IP 状态 # rate=10r/s → 每秒最多 10 个请求(令牌生成速率) limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
# 日志级别(默认 error,改为 warn 减少误告警) limit_req_status 429; # 超限返回 429 Too Many Requests(比 503 更语义化) limit_req_log_level warn;
server { location /api/ { # burst=20 → 允许最多 20 个请求排队(突发容忍) # nodelay → burst 内的请求立即处理,不人为延迟 limit_req zone=req_limit burst=20 nodelay;
proxy_pass http://backend; } }}漏桶算法理解
rate=10r/s, burst=20 的效果:
正常流量(10 QPS 以下):全部通过,无延迟突发流量(10-30 QPS):前 20 个超出的请求进入 burst 队列,立即处理(nodelay)极端流量(> 30 QPS):第 31 个及以上请求直接返回 429恢复:每 100ms 消耗一个令牌,令牌耗尽前不接受新请求分级限流(不同接口不同策略)
http { # API 接口:严格限流 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; # 登录接口:防暴力破解,更严格 limit_req_zone $binary_remote_addr zone=login_limit:5m rate=3r/m; # 静态资源:宽松限流 limit_req_zone $binary_remote_addr zone=static_limit:5m rate=50r/s;
server { # API 接口限流 location /api/ { limit_req zone=api_limit burst=20 nodelay; proxy_pass http://backend; }
# 登录接口:每分钟最多 3 次,无突发容忍 location /api/login { limit_req zone=login_limit burst=3 nodelay; proxy_pass http://backend; }
# 静态资源:允许较大突发 location /static/ { limit_req zone=static_limit burst=100 nodelay; root /var/www; } }}白名单跳过限流
http { # 根据 IP 设置 limit_req_key:内网 IP 不限流(设为空字符串) geo $limit_key { default $binary_remote_addr; 127.0.0.1 ""; 10.0.0.0/8 ""; # 内网 IP 不限流 192.168.0.0/16 ""; }
limit_req_zone $limit_key zone=req_limit:10m rate=10r/s;
server { location /api/ { # $limit_key 为空时(内网 IP),limit_req 模块自动跳过 limit_req zone=req_limit burst=20 nodelay; proxy_pass http://backend; } }}2.2 limit_conn:并发连接限制
http { # 按 IP 限制并发连接数 limit_conn_zone $binary_remote_addr zone=conn_limit:10m; limit_conn_status 429;
server { location /api/ { limit_conn conn_limit 20; # 单个 IP 最多 20 个并发连接 proxy_pass http://backend; }
# 下载接口:严格限制并发(防止单用户占满带宽) location /download/ { limit_conn conn_limit 3; # 单 IP 最多 3 个并发下载 limit_rate 2m; # 每个连接限速 2MB/s root /var/www/files; } }}2.3 双重限流组合(生产推荐)
http { limit_req_zone $binary_remote_addr zone=req_limit:10m rate=20r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server { location /api/ { # 先限并发连接,再限请求速率 limit_conn conn_limit 50; limit_req zone=req_limit burst=30 nodelay;
proxy_pass http://backend;
# 返回 429 时给客户端友好提示 error_page 429 /rate_limit.html; } }}三、proxy_cache 缓存加速
Nginx 的 proxy_cache 模块可以将后端响应缓存在本地磁盘/内存,大幅降低后端压力,典型场景:
- 高频 API 响应缓存(排行榜、配置接口)
- 图片/视频等静态资源缓存
- 慢查询 HTML 页面缓存
3.1 缓存区定义(http 块)
http { # proxy_cache_path 参数说明: # /var/cache/nginx → 缓存存储目录(需提前创建) # levels=1:2 → 二级目录结构,避免单目录文件过多 # keys_zone=main:100m → 共享内存区名称:大小(存储 key 的索引,100MB ≈ 800,000 个 key) # max_size=10g → 磁盘缓存最大容量(超出 LRU 淘汰) # inactive=60m → 60 分钟内未被访问的缓存自动清除 # use_temp_path=off → 直接写入目标目录(减少一次文件拷贝,性能更好) proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=main_cache:100m max_size=10g inactive=60m use_temp_path=off;}# 创建缓存目录并设置正确权限mkdir -p /var/cache/nginxchown nginx:nginx /var/cache/nginx3.2 启用缓存(location 块)
server { location /api/public/ { proxy_cache main_cache; # 使用定义的缓存区 proxy_cache_key "$scheme$host$request_uri"; # 缓存 key(URL 维度) proxy_cache_lock on; # 同一 key 并发请求只放行一个到后端(防穿透) proxy_cache_lock_timeout 5s; # 等待锁超时后直接转发到后端
# 按后端响应状态码设置不同 TTL proxy_cache_valid 200 301 302 10m; # 成功响应缓存 10 分钟 proxy_cache_valid 404 1m; # 404 缓存 1 分钟(防恶意探测) proxy_cache_valid any 30s; # 其他状态码缓存 30 秒
# 后端故障时用旧缓存兜底(降级保障) proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# 在响应头中添加缓存状态,便于调试 add_header X-Cache-Status $upstream_cache_status; add_header X-Cache-Key "$scheme$host$request_uri";
proxy_pass http://backend; }}3.3 缓存状态说明(X-Cache-Status)
| 状态值 | 含义 | 排查方向 |
|---|---|---|
HIT | 缓存命中,直接返回 | 正常,说明缓存生效 |
MISS | 缓存未命中,已回源 | 首次访问或缓存过期,正常 |
BYPASS | 触发了绕过规则(见 3.4) | 检查 proxy_cache_bypass 配置 |
EXPIRED | 缓存过期,已回源刷新 | 正常老化 |
UPDATING | 正在更新中(旧缓存兜底) | 配合 stale-while-revalidate 使用 |
STALE | 后端故障,返回过期缓存 | 降级保障触发,排查后端状态 |
3.4 缓存绕过与穿透防护
location /api/ { proxy_cache main_cache;
# ── 绕过缓存(满足条件时不走缓存,直接回源)────────────── # 场景:带特定请求头时强制刷新缓存(如内部运维工具刷新) proxy_cache_bypass $http_x_cache_purge;
# 场景:POST 请求不缓存 proxy_no_cache $request_method;
# 场景:登录用户不走缓存(通过 Cookie 判断) set $no_cache 0; if ($http_cookie ~* "session_id=") { set $no_cache 1; } proxy_no_cache $no_cache; proxy_cache_bypass $no_cache;
# ── 忽略后端的缓存控制头(强制缓存后端本不想缓存的响应)── # 谨慎使用,仅对明确安全的接口启用 # proxy_ignore_headers Cache-Control Expires Set-Cookie;
proxy_pass http://backend;}3.5 缓存命中率调优要点
低命中率常见原因:
1. URL 含动态参数(?t=1234567890) → 解决:在 proxy_cache_key 中去除时间戳参数 proxy_cache_key "$scheme$host$uri?$filtered_args";
2. 请求带 Cookie 导致 BYPASS → 解决:set $no_cache 只对登录 Cookie 判断,非登录 Cookie 不影响缓存
3. 缓存 TTL 过短(inactive 时间内未命中) → 解决:根据业务特点适当延长 proxy_cache_valid
4. 后端响应含 Cache-Control: no-cache → 解决:与后端协商修改,或用 proxy_ignore_headers 忽略(需谨慎)四、WebSocket 长连接穿透
WebSocket 是全双工长连接协议,与 HTTP 短连接模型不同,需要特殊配置才能正确穿透 Nginx。
4.1 基础 WebSocket 配置
http { # WebSocket 协议升级映射(处理 Upgrade 头) map $http_upgrade $connection_upgrade { default upgrade; '' close; }
server { listen 443 ssl; server_name ws.example.com;
location /ws/ { proxy_pass http://websocket_backend;
# ── WebSocket 必须配置项 ──────────────────────────── proxy_http_version 1.1; # 必须使用 HTTP/1.1 proxy_set_header Upgrade $http_upgrade; # 传递 Upgrade 头 proxy_set_header Connection $connection_upgrade; # 使用 map 变量
# ── 长连接保活 ────────────────────────────────────── proxy_read_timeout 3600s; # WebSocket 长连接,延长读超时(默认 60s 会断连) proxy_send_timeout 3600s; # 延长写超时 proxy_connect_timeout 10s; # 连接超时保持正常值
# ── 传递真实客户端信息 ────────────────────────────── 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; } }
upstream websocket_backend { # WebSocket 服务器通常有状态,建议 ip_hash 保持连接 ip_hash; server 10.0.0.1:3000; server 10.0.0.2:3000; keepalive 100; # 维持后端长连接池 }}4.2 WebSocket + SSL(WSS)配置
server { listen 443 ssl http2; server_name ws.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# HTTP → HTTPS 重定向 location / { return 301 https://$server_name$request_uri; }
# WSS 路径 location /wss/ { proxy_pass http://websocket_backend; # 后端可以是普通 WS(不需要 SSL) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 86400s; # 24 小时超时(根据业务调整) proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }}4.3 WebSocket 心跳与断线问题排查
问题:WebSocket 连接频繁断开
可能原因与解决:
| 原因 | 排查方法 | 解决方案 |
|---|---|---|
proxy_read_timeout 过短(默认 60s) | 查看 Nginx error.log 是否有 upstream timed out | 将 proxy_read_timeout 延长至 3600s 以上 |
| 防火墙/负载均衡 TCP 空闲超时 | 抓包查看是否有 RST | 在应用层实现心跳(每 30s 发一次 ping) |
| upstream keepalive 不足 | 查看 Active connections 是否达到上限 | 增大 keepalive 值 |
| 后端进程崩溃 | 查看后端进程状态 | 用 PM2/systemd 确保自动重启 |
五、SSL 双向认证(mTLS)
标准 HTTPS 只验证服务器证书(单向),mTLS(Mutual TLS) 要求客户端也提供证书,服务端验证客户端身份,常用于:
- 微服务内部通信(服务间互信)
- API 网关对接企业客户(限制接入方)
- IoT 设备身份验证
5.1 生成客户端证书(测试用)
# 1. 生成 CA 私钥和自签名证书openssl req -x509 -newkey rsa:4096 \ -keyout ca.key -out ca.crt \ -days 3650 -nodes \ -subj "/CN=MyCA/O=Example/C=CN"
# 2. 生成客户端私钥和 CSRopenssl req -newkey rsa:2048 \ -keyout client.key -out client.csr \ -nodes \ -subj "/CN=client001/O=Example/C=CN"
# 3. 用 CA 签发客户端证书openssl x509 -req -in client.csr \ -CA ca.crt -CAkey ca.key \ -CAcreateserial -out client.crt \ -days 365
# 4. 打包为 PKCS12 格式(浏览器/curl 使用)openssl pkcs12 -export \ -in client.crt -inkey client.key \ -out client.p12 \ -name "client001"5.2 Nginx mTLS 配置
server { listen 443 ssl; server_name api.example.com;
# 服务器证书(标准配置) ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key;
# ── mTLS 核心配置 ──────────────────────────────────────── # 指定用于验证客户端证书的 CA ssl_client_certificate /etc/nginx/ssl/ca.crt;
# on:必须提供客户端证书,否则拒绝连接 # optional:客户端证书可选(可在应用层自行判断) # optional_no_ca:接受任意客户端证书(仅用于调试) ssl_verify_client on;
# 证书链验证深度(CA 中间证书数量) ssl_verify_depth 2;
# ── 将客户端证书信息传递给后端 ────────────────────────── location /api/ { proxy_pass http://backend;
# 客户端证书的 DN(Distinguished Name) proxy_set_header X-Client-Cert-DN $ssl_client_s_dn; # 证书验证结果(SUCCESS/FAILED/NONE) proxy_set_header X-Client-Verify $ssl_client_verify; # 客户端证书的序列号 proxy_set_header X-Client-Cert-Serial $ssl_client_serial; }}5.3 curl 测试 mTLS
# 使用客户端证书访问 mTLS 接口curl --cert client.crt --key client.key \ --cacert ca.crt \ https://api.example.com/api/data
# 或使用 PKCS12 格式curl --cert-type P12 --cert client.p12:password \ --cacert ca.crt \ https://api.example.com/api/data
# 不提供证书(预期被拒绝,返回 400)curl --cacert ca.crt https://api.example.com/api/data六、动静分离与 Gzip 压缩
6.1 动静分离配置
server { # 静态资源:直接由 Nginx 处理,不走后端 location ~* \.(jpg|jpeg|png|gif|svg|ico|css|js|woff2|woff|ttf|eot)$ { root /var/www/static;
# 浏览器缓存:静态资源设置较长过期时间 expires 30d; add_header Cache-Control "public, no-transform";
# 访问日志:静态资源流量大,可关闭日志减少磁盘 I/O access_log off;
# 如果文件不存在,尝试回退到后端(适合 SPA 应用) try_files $uri @backend; }
# 动态请求:转发到后端应用 location / { proxy_pass http://backend; }
location @backend { proxy_pass http://backend; }}6.2 Gzip 压缩
http { gzip on; gzip_min_length 1024; # 小于 1KB 的响应不压缩(压缩收益低) gzip_comp_level 5; # 压缩级别 1-9(6 是速度与压缩率平衡点) gzip_vary on; # 添加 Vary: Accept-Encoding 响应头 gzip_proxied any; # 对代理请求也启用压缩 gzip_buffers 16 8k;
# 需要压缩的 MIME 类型 gzip_types text/plain text/css text/javascript text/xml application/json application/javascript application/xml application/xml+rss image/svg+xml font/woff font/woff2;
# 禁止 IE 6 的 gzip(该浏览器 gzip 有 bug) gzip_disable "MSIE [1-6]\.";}七、生产级性能调优清单
7.1 Worker 进程与连接数
# nginx.conf 主配置worker_processes auto; # 自动匹配 CPU 核心数worker_rlimit_nofile 65536; # 每个 worker 的最大文件描述符数
events { use epoll; # Linux 使用 epoll(高性能 I/O 模型) worker_connections 4096; # 每个 worker 最大并发连接数 multi_accept on; # 一次性接受所有新连接 accept_mutex off; # 高并发时关闭(减少锁竞争)}7.2 完整生产级配置清单
http { # ── 性能 ──────────────────────────────────────────────── sendfile on; # 零拷贝文件传输 tcp_nopush on; # 减少网络包数量 tcp_nodelay on; # 降低延迟(实时应用) keepalive_timeout 65s; keepalive_requests 1000; # 每个长连接最多处理 1000 个请求
# ── 缓冲区 ────────────────────────────────────────────── client_body_buffer_size 128k; client_max_body_size 50m; # 上传文件最大 50MB client_header_buffer_size 1k; large_client_header_buffers 4 8k;
proxy_buffer_size 16k; proxy_buffers 8 32k; proxy_busy_buffers_size 64k;
# ── 超时 ──────────────────────────────────────────────── client_header_timeout 15s; client_body_timeout 15s; send_timeout 30s;
# ── 安全 ──────────────────────────────────────────────── 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";}7.3 调优效果验证
# 测试并发性能(ab 工具)ab -n 10000 -c 200 https://example.com/api/data
# 测试限流是否生效for i in {1..30}; do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/api/datadone# 前 20 个应返回 200,超出后返回 429
# 查看缓存命中率curl -I https://example.com/api/public/list | grep X-Cache-Status
# 查看实时连接状态watch -n 1 'curl -s http://127.0.0.1:8080/nginx_status'
# 测试 WebSocket 连接wscat -c wss://ws.example.com/ws/八、常见问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
502 Bad Gateway | 后端不可达或崩溃 | 检查后端进程状态;检查 proxy_connect_timeout 是否过短 |
504 Gateway Timeout | 后端响应超时 | 增大 proxy_read_timeout;排查后端慢查询 |
429 Too Many Requests | 限流触发 | 检查 limit_req 配置;确认是否为正常流量 |
| WebSocket 连接 60s 后断开 | proxy_read_timeout 默认 60s | 增大至 3600s;在应用层加心跳 |
| 缓存全部 BYPASS | 请求带 Session Cookie | 检查 proxy_no_cache / proxy_cache_bypass 配置 |
| mTLS 返回 400 | 客户端未提供证书或证书 CA 不匹配 | 检查 ssl_client_certificate 指定的 CA;用 curl 携带证书测试 |
上传大文件 413 Request Entity Too Large | client_max_body_size 太小 | 增大该值(如 client_max_body_size 100m) |
总结
本文覆盖了 Nginx 生产级进阶配置的五大核心主题:
| 主题 | 核心配置 | 主要价值 |
|---|---|---|
| 负载均衡 | upstream + least_conn + proxy_next_upstream | 高可用、故障自动摘除 |
| 限流防护 | limit_req + limit_conn + 白名单 | 防 CC 攻击、接口滥用 |
| 缓存加速 | proxy_cache_path + proxy_cache_valid + use_stale | 降低后端压力、提升响应速度 |
| WebSocket | Upgrade + Connection + 长超时 | 实时应用支持 |
| mTLS | ssl_verify_client + 客户端证书 | 服务间双向认证 |
结合 Nginx 反向代理基础配置 与本文进阶内容,可以构建一套完整的生产级 Nginx 配置体系。
相关文章:
- Nginx 反向代理配置实战完全指南:从入门到生产部署
- Docker Compose 实战:多容器编排与 Nginx 反代
- SSH 完全指南:隧道、转发与安全配置
- HTTPS/SSL 完全指南:证书申请、配置与续期
本文所有配置均经过实际验证,生产使用前请根据具体业务场景调整参数值。
Nginx 进阶实战完全指南:负载均衡策略 + 限流模块 + 缓存加速 + WebSocket + SSL 双向认证
https://971918.xyz/posts/docs/nginx-advanced-guide/