一、问题背景
Nginx 几乎是每个互联网公司的接入层标配,但很多初中级运维的状态是:
- 配置写得过且过,路径跳转、rewrite、HTTPS 全靠搜索引擎复制粘贴
- 出了问题靠重启,重启无效就重启机器
- accesslog 看不下去,errorlog 满屏 502/504 不知道从哪里开始
- worker_cpu 100% 时不知道怎么定位
- 500 个 502 是上游崩了还是 Nginx 自己拒了,根本分不清
- 老板问“能不能扛住双 11”,心里没底
这一篇要解决的是“合格运维对 Nginx 应有的知识地图”。覆盖:架构、配置、模块、HTTPS、反向代理、负载均衡、限流、日志、调优、监控、高可用、平滑升级、典型排障,最后落到 6 套生产级配置示例。
写作目标:
- 学完能独立写出生产级
nginx.conf - 能排 80% 的常见故障(502/504、worker CPU 高、连接打满、磁盘写满、慢响应)
- 能调优到单 worker 5 万 QPS 量级
- 能配合 Prometheus、Grafana 形成完整监控告警
二、适用场景
- 静态资源(HTML、CSS、JS、图片、字体、音视频)服务
- 反向代理 + 负载均衡(HTTP/1.1、HTTP/2、gRPC)
- API 网关层限流、熔断、灰度
- HTTPS 终止、证书自动续签(Let’s Encrypt、ACME)
- WAF 与防 CC 攻击
- 防盗链、防爬虫
- 微服务入口(Spring Cloud Gateway、Kong、APISIX 之前)
- 文件下载(大文件断点续传、Range)
- WebSocket 反代
- TCP/UDP 四层负载(stream 模块)
- 与 Consul、etcd、Nacos 注册中心联动
- 在 Kubernetes 中作为 Ingress Controller
- CDN 回源
- IPv6 接入
三、核心知识点
3.1 Nginx 架构
Nginx 是事件驱动的高性能 Web 服务器。核心模型是:
- 一个 master 进程,负责加载配置、创建 worker、升级、平滑退出
- 多个 worker 进程,处理实际的请求(默认与 CPU 核数相同)
- 一个可选的 cache manager / cache loader 进程,处理磁盘缓存
worker 的几个关键点:
- 每个 worker 是单线程,事件循环 + epoll(Linux)/ kqueue(BSD)
- 多个 worker 之间互不抢连接,靠 OS 内核的 epoll accept 互斥锁(
accept_mutex) - 静态资源、HTTP 反代、stream 反代都共用同一个 worker
- 一个 worker 默认能并行处理上万个连接(受限于
worker_connections)
事件驱动模型的优点:
- 没有线程上下文切换开销
- 没有每个连接的内存占用(线程栈默认 1MB~8MB)
- 内存占用稳定,不随并发线性增长
事件驱动模型的限制:
- 不能在请求处理里跑 CPU 密集型阻塞调用
- 不能直接访问阻塞型第三方库(需要异步库或线程池)
3.2 进程模型与信号
Nginx 用信号控制:
nginx -s stop:发 SIGTERM,优雅停止nginx -s quit:发 SIGQUIT,worker 处理完所有连接再退出nginx -s reload:发 SIGHUP,master 重新加载配置,旧 worker 处理完连接后退出nginx -s reopen:发 SIGUSR1,重新打开日志(logrotate 配合使用)kill -USR2 <master_pid>:热升级,新 master 启动kill -WINCH <old_master_pid>:通知旧 master 关闭 worker
热升级流程:
bash# 备份旧 binary
cp /usr/sbin/nginx /usr/sbin/nginx.old
# 用新 binary 替换
cp /usr/local/nginx/sbin/nginx /usr/sbin/nginx
# 触发热升级
kill -USR2 <old_master_pid>
# 新 master 启动,旧 master 改名为 .old,worker 也变 .old
# 旧 worker 继续处理现有连接,新 worker 接受新连接
# 等所有旧连接结束
kill -WINCH <old_master_pid>
# 关闭旧 master
kill -QUIT <old_master_pid>
# 如果新版本有问题,回滚
kill -HUP <old_master_pid>
# 新版本会平滑退出,回到旧版本处理
3.3 配置结构
Nginx 配置是层级化的,每段都有自己作用域:
- main:
user、worker_processes、error_log、pid、worker_rlimit_nofile - events:
worker_connections、multi_accept、use - http:
include、default_type、log_format、access_log、sendfile、tcp_nopush、tcp_nodelay、keepalive_timeout、gzip、upstream - server:
listen、server_name、root、location、access_log、error_page、return、rewrite - location:
proxy_pass、try_files、root、alias、index、limit_req、auth_basic - upstream:
server、ip_hash、least_conn、keepalive、health_check
变量与执行顺序:
- 变量以
$开头,例如$remote_addr、$http_user_agent、$arg_name - 变量在
http、server、location、if、map、geo、set中被赋值 - 配置执行顺序:
http → server → location → if,子级覆盖父级
3.4 模块体系
Nginx 模块分为:
- 核心模块(Core):
main、events、http等基础指令 - HTTP 模块:
http_core、http_log、http_gzip、http_ssl、http_proxy、http_upstream、http_rewrite、http_limit_req、http_limit_conn、http_auth_request、http_secure_link、http_stub_status、http_v2、http_slice - Stream 模块(TCP/UDP):
stream_core、stream_proxy、stream_upstream、stream_ssl、stream_limit_conn、stream_log - 邮件模块(基本不用)
查看编译参数:
bashnginx -V 2>&1 | tr ' ' '\n' | grep -E '^--'
第三方模块:
- nginx-module-vts:实时流量监控
- nginx-mod-http-geoip2:GeoIP
- nginx-module-brotli:brotli 压缩
- lua-nginx-module + OpenResty:嵌入 Lua
- nginx-upsync-module:从 Consul/etcd 动态 upstream
- nginx-jwt-module:JWT 校验
3.5 常用指令
nginxuser www www;
worker_processes auto;
worker_rlimit_nofile65535;
pid /var/run/nginx.pid;
error_log /var/log/nginx/error.log warn;
events {
worker_connections10240;
multi_accepton;
useepoll;
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_tokensoff;
client_max_body_size50m;
client_body_buffer_size128k;
client_header_buffer_size1k;
large_client_header_buffers48k;
sendfileon;
tcp_nopushon;
tcp_nodelayon;
keepalive_timeout65;
keepalive_requests1000;
types_hash_max_size2048;
server_names_hash_bucket_size128;
proxy_http_version1.1;
proxy_set_header Connection "";
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
open_file_cache max=10240 inactive=20s;
open_file_cache_valid30s;
open_file_cache_min_uses2;
open_file_cache_errorson;
gzipon;
gzip_min_length1k;
gzip_comp_level5;
gzip_types text/plain text/css application/json application/javascript application/xml;
include /etc/nginx/conf.d/*.conf;
}
3.6 静态资源服务
nginxserver {
listen80;
server_name static.example.com;
root /data/www/static;
index index.html;
location / {
try_files$uri$uri/ =404;
}
location~* \.(jpg|jpeg|png|gif|webp|avif)$ {
expires30d;
add_header Cache-Control "public, immutable";
access_logoff;
}
location~* \.(css|js)$ {
expires7d;
access_logoff;
}
location~* \.(mp4|webm|m4a)$ {
mp4;
mp4_buffer_size4m;
mp4_max_buffer_size10m;
}
}
关键指令:
try_files $uri $uri/ =404:依次尝试文件、目录、最后返回 404expires 30d:浏览器缓存 30 天mp4:启用 MP4 模块支持伪流access_log off:关掉静态资源日志
3.7 反向代理与负载均衡
nginxupstream backend {
ip_hash;
server10.0.0.1:8080 max_fails=3 fail_timeout=30s weight=1;
server10.0.0.2:8080 max_fails=3 fail_timeout=30s weight=1;
server10.0.0.3:8080 max_fails=3 fail_timeout=30s weight=1;
keepalive64;
keepalive_timeout60s;
keepalive_requests1000;
}
server {
listen80;
server_name app.example.com;
location / {
proxy_pass http://backend;
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_http_version1.1;
proxy_set_header Connection "";
proxy_connect_timeout5s;
proxy_send_timeout30s;
proxy_read_timeout30s;
proxy_bufferingon;
proxy_buffer_size16k;
proxy_buffers832k;
proxy_busy_buffers_size64k;
}
}
负载均衡算法:
round-robin(默认):轮询weight:权重ip_hash:按 IP 哈希,固定上游least_conn:最少连接least_time:最少响应时间(商业版)random:随机hash $key consistent:一致性哈希url_hash:按 URL 哈希(第三方模块)
健康检查:
- 被动:
max_fails、fail_timeout - 主动:
health_check(商业版)或ngx_http_upstream_check_module(开源)
3.8 HTTPS 与 TLS
nginxserver {
listen443 ssl http2;
server_name secure.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout1d;
ssl_session_ticketson;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_cipherson;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
}
证书自动续签(Let’s Encrypt):
bash# 安装 certbot
apt install -y certbot python3-certbot-nginx
# 申请证书
certbot --nginx -d example.com -d www.example.com
# 自动续签(systemd timer)
systemctl enable certbot.timer
systemctl start certbot.timer
# 手动测试
certbot renew --dry-run
3.9 限流
3.9.1 limit_req_zone
nginxhttp {
limit_req_zone$binary_remote_addr zone=perip:10m rate=10r/s;
limit_req_zone$server_name zone=perserver:10m rate=1000r/s;
limit_req_zone$http_x_api_key zone=perkey:10m rate=100r/s;
server {
location /api/ {
limit_req zone=perip burst=20 nodelay;
limit_req_status429;
}
}
}
参数:
$binary_remote_addr:按 IP$server_name:按 server$http_x_api_key:按 API Keyrate=10r/s:每秒 10 个burst=20:突发 20nodelay:超过立即返回 429,不排队
3.9.2 limit_conn_zone
nginxhttp {
limit_conn_zone $binary_remote_addr zone=perip_conn:10m;
server {
location /download/ {
limit_conn perip_conn 5;
limit_conn_status 503;
}
}
}
3.9.3 黑白名单
nginxhttp {
geo$blocked {
default0;
10.0.0.0/8 0;
192.168.1.0/24 1;
1.2.3.4 1;
}
map$http_user_agent$is_bot {
default0;
~*bot1;
~*spider1;
~*crawler1;
}
server {
if ($blocked) { return403; }
if ($is_bot) { return403; }
}
}
3.10 访问控制
nginxlocation /admin/ {
allow10.0.0.0/8;
allow192.168.0.0/16;
deny all;
auth_basic"Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /api/ {
auth_request /auth;
}
location = /auth {
internal;
proxy_pass http://auth-service/verify;
proxy_set_header X-Original-URI $request_uri;
}
3.11 rewrite 与 return
nginx# 强制 HTTPS
server {
listen80;
server_name example.com www.example.com;
return301 https://$host$request_uri;
}
# 隐藏 .php 扩展
location / {
rewrite ^/(.*)\.php$ /$1last;
}
# 旧 URL 跳转
location /old/path {
return301 /new/path;
}
# 反盗链
location~* \.(jpg|png|gif)$ {
valid_referersnoneblocked example.com *.example.com;
if ($invalid_referer) {
return403;
}
}
return 与 rewrite 的区别:
return直接返回响应,不再处理后续指令rewrite改写 URI 后重新匹配 location
3.12 日志
nginxlog_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time",'
'"upstream_addr":"$upstream_addr",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.json json_combined buffer=64k flush=5s;
日志切割(logrotate):
bashcat > /etc/logrotate.d/nginx <<'EOF'
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi
endscript
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
EOF
3.13 性能调优
关键参数:
worker_processes auto:与 CPU 核数相同worker_rlimit_nofile 65535:单 worker 最大文件描述符worker_connections 10240:单 worker 最大连接数multi_accept on:一次 accept 多个连接use epoll:使用 epollsendfile on:零拷贝发送文件tcp_nopush on:合并小包tcp_nodelay on:Nagle 算法关闭keepalive_timeout 65:长连接保持keepalive_requests 1000:单连接最大请求数gzip on:开启 gzipgzip_comp_level 5:压缩级别open_file_cache:文件描述符缓存worker_cpu_affinity:CPU 亲和性
CPU 亲和性:
nginxworker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
3.14 健康检查
nginxupstream 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;
health_check interval=5s fails=3 passes=2 uri=/health;
}
max_fails=3:连续 3 次失败标记为 downfail_timeout=30s:30s 后重新探测health_check 是商业版功能,开源版用 ngx_http_upstream_check_module
3.15 高可用
3.15.1 keepalived + VIP
两台 Nginx 主备,VIP 在主机器上。
主:
nginxvrrp_script chk_nginx {
script"/usr/local/bin/check_nginx.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass SECRET
}
virtual_ipaddress {
10.0.0.100/24
}
track_script {
chk_nginx
}
}
3.15.2 双 Nginx + DNS
主备 Nginx,DNS 解析到主;主故障时通过脚本切换 DNS(一般使用 api TTL 较短的方式)。
3.15.3 LVS + Nginx
LVS 四层负载,后端是多个 Nginx。
3.16 安全加固
- 隐藏版本号:
server_tokens off - 限制请求方法:
limit_except GET POST { deny all; } - 防 CC:
limit_req+limit_conn - IP 黑名单:
geo或map - 防盗链:
secure_link或valid_referers - 防扫描:
map $http_user_agent+if - 限制请求体大小:
client_max_body_size - 限制 Header 数量:
large_client_header_buffers - 限制连接频率:
limit_req
secure_link 防盗链:
nginxlocation /download/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "SECRET$uri$arg_expires";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
root /data/www;
}
3.17 平滑升级
bash# 备份
cp /usr/sbin/nginx /usr/sbin/nginx.bak
# 编译新版本到不同目录
./configure --prefix=/usr/local/nginx-new
make
make install
# 用 nginx -V 拿到原编译参数再编译
nginx -V 2>&1 | grep configure
# 复制新 binary 替换
cp /usr/local/nginx-new/sbin/nginx /usr/sbin/nginx
# 触发热升级
kill -USR2 <master_pid>
# 等旧 worker 处理完
sleep 10
kill -WINCH <old_master_pid>
# 关掉旧 master
kill -QUIT <old_master_pid>
# 回滚
kill -HUP <old_master_pid>
四、整体排查或实施思路
4.1 故障排查主线
- 第一步:拿到现象(响应码、耗时、错误页、客户端报错)
- 第二步:看 Nginx errorlog
- 第三步:看 accesslog 找异常请求
- 第四步:看
nginx -V编译参数和当前配置 - 第五步:看
ss -s、netstat -s看连接数 - 第六步:看上游日志
- 第七步:看 CPU、内存、磁盘
4.2 部署优化主线
- 第一步:环境假设(CPU、内存、QPS、并发、磁盘)
- 第二步:编译参数与模块准备
- 第三步:写
nginx.conf - 第四步:分批 reload 验证
- 第五步:上线监控
- 第六步:压测验证
五、实战步骤
5.1 安装 Nginx
5.1.1 包管理器(Debian/Ubuntu)
bashapt update
apt install -y nginx
nginx -v
systemctl enable nginx
systemctl start nginx
5.1.2 包管理器(CentOS/RHEL)
bashyum install -y epel-release
yum install -y nginx
systemctl enable nginx
systemctl start nginx
5.1.3 源码编译
bash# 安装依赖
yum install -y gcc make pcre-devel zlib-devel openssl-devel
# 下载
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar zxf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 配置
./configure \
--prefix=/usr/local/nginx \
--user=www --group=www \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_gzip_static_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_sub_module \
--with-stream \
--with-stream_ssl_module \
--with-pcre \
--with-pcre-jit \
--add-module=/path/to/nginx-module-vts
# 编译安装
make -j$(nproc)
make install
# 添加 systemd 单元
cat > /etc/systemd/system/nginx.service <<'EOF'
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
5.2 配置文件组织
bash# 推荐结构
/etc/nginx/
├── nginx.conf # 主配置
├── mime.types
├── conf.d/ # 业务 server
│ ├── default.conf
│ ├── api.conf
│ └── static.conf
├── snippets/ # 复用片段
│ ├── ssl-params.conf
│ ├── proxy-params.conf
│ └── security-headers.conf
├── ssl/ # 证书
│ ├── example.com.crt
│ └── example.com.key
└── logrotate.d/
└── nginx
主配置:
nginxuser www www;
worker_processes auto;
worker_rlimit_nofile65535;
pid /var/run/nginx.pid;
error_log /var/log/nginx/error.log warn;
events {
worker_connections10240;
multi_accepton;
useepoll;
}
http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_tokensoff;
sendfileon;
tcp_nopushon;
tcp_nodelayon;
keepalive_timeout65;
keepalive_requests1000;
client_max_body_size50m;
client_body_buffer_size128k;
client_header_buffer_size1k;
large_client_header_buffers48k;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
5.3 配置 HTTPS 站点
操作目的:让一个域名支持 HTTPS。
步骤:
bash# 申请证书
certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com
# 证书位置
ls -la /etc/letsencrypt/live/example.com/
# fullchain.pem privkey.pem
/etc/nginx/conf.d/example.com.conf:
nginxserver {
listen80;
server_name example.com www.example.com;
return301 https://$host$request_uri;
}
server {
listen443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;
root /var/www/example.com;
index index.html;
location / {
try_files$uri$uri/ =404;
}
}
/etc/nginx/snippets/ssl-params.conf:
nginxssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_cipherson;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout1d;
ssl_session_ticketson;
ssl_staplingon;
ssl_stapling_verifyon;
resolver1.1.1.18.8.8.8 valid=300s;
resolver_timeout5s;
add_header Strict-Transport-Security "max-age=63072000" always;
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 "no-referrer-when-downgrade" always;
生效:
bashnginx -t
systemctl reload nginx
验证:
bashcurl -vI https://example.com
nmap --script ssl-enum-ciphers -p 443 example.com
openssl s_client -connect example.com:443 -servername example.com </dev/null
5.4 反向代理 + 负载均衡
nginxupstream backend {
least_conn;
server10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server10.0.0.3:8080 max_fails=3 fail_timeout=30s;
keepalive64;
keepalive_timeout60s;
}
server {
listen80;
server_name api.example.com;
access_log /var/log/nginx/api.example.com.access.log main;
location / {
proxy_pass http://backend;
include /etc/nginx/snippets/proxy-params.conf;
}
location /api/v1/health {
access_logoff;
return200'{"status":"ok"}';
add_header Content-Type application/json;
}
}
/etc/nginx/snippets/proxy-params.conf:
nginxproxy_http_version 1.1;
proxy_set_header Connection "";
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_connect_timeout5s;
proxy_send_timeout30s;
proxy_read_timeout30s;
proxy_bufferingon;
proxy_buffer_size16k;
proxy_buffers832k;
proxy_busy_buffers_size64k;
proxy_next_upstreamerror timeout http_502 http_503 http_504;
proxy_next_upstream_tries3;
proxy_next_upstream_timeout10s;
5.5 限流实战
5.5.1 全局 IP 限流
nginxhttp {
limit_req_zone $binary_remote_addr zone=global:10m rate=100r/s;
server {
location / {
limit_req zone=global burst=200 nodelay;
limit_req_status 429;
}
}
}
5.5.2 登录接口防撞库
nginxhttp {
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
location /api/login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://backend;
}
}
}
5.5.3 业务 API 区分用户等级
nginxhttp {
limit_req_zone$http_x_api_key zone=apikey:10m rate=1000r/s;
limit_req_zone$arg_token zone=token:10m rate=10r/s;
server {
location /api/ {
if ($http_x_api_key) {
set$limit_zone apikey;
}
if ($arg_token) {
set$limit_zone token;
}
limit_req zone=$limit_zone burst=20 nodelay;
}
}
}
5.6 大文件下载与限速
nginxserver {
listen80;
server_name files.example.com;
root /data/files;
access_log /var/log/nginx/files.access.log;
location / {
limit_rate10m; # 单连接 10MB/s
limit_rate_after10m; # 头 10MB 不限速
limit_conn perip 2; # 单 IP 最多 2 个连接
limit_conn perserver 1000; # 服务器总连接 1000
}
}
5.7 WebSocket 反代
nginxupstream websocket {
server10.0.0.1:8081;
server10.0.0.2:8081;
}
server {
listen80;
server_name ws.example.com;
location / {
proxy_pass http://websocket;
proxy_http_version1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout600s; # 长连接超时
proxy_send_timeout600s;
}
}
5.8 gRPC 反代
nginxupstream grpc_backend {
server10.0.0.1:50051;
server10.0.0.2:50051;
keepalive32;
}
server {
listen443 ssl http2;
server_name grpc.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
grpc_pass grpc://grpc_backend;
grpc_set_header Host $host;
grpc_connect_timeout5s;
}
}
5.9 TCP/UDP 四层负载
nginxstream {
upstream mysql_backend {
server10.0.0.1:3306 max_fails=3 fail_timeout=30s;
server10.0.0.2:3306 max_fails=3 fail_timeout=30s;
}
server {
listen3306;
proxy_pass mysql_backend;
proxy_connect_timeout5s;
proxy_timeout600s;
}
upstream dns_backend {
server8.8.8.8:53;
server1.1.1.1:53;
}
server {
listen53 udp;
proxy_pass dns_backend;
}
}
5.10 启用 stub_status
nginxserver {
listen 127.0.0.1:80;
server_name 127.0.0.1;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
查看:
bashcurl http://127.0.0.1/nginx_status
# Active connections: 291
# server accepts handled requests
# 16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106
Reading + Writing + Waiting 之和应小于 worker_connections * worker_processes。
5.11 启用 vts 模块
nginxhttp {
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_hoston;
vhost_traffic_status_filter_by_upstreamon;
server {
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
allow127.0.0.1;
deny all;
}
}
}
5.12 Prometheus 监控
使用 nginx_exporter 或 nginx-prometheus-exporter:
bash# 启动 nginx-prometheus-exporter
nginx-prometheus-exporter -nginx.scrape-uri=http://127.0.0.1:80/nginx_status -web.listen-address=:9113
或使用 nginxinc/nginx-prometheus-exporter,配合 vts 模块。
Prometheus 配置:
yamlscrape_configs:
- job_name: nginx
static_configs:
- targets: ['nginx-host:9113']
scrape_interval: 15s
5.13 排障:worker_cpu 100%
现象:worker 进程 CPU 100%。
初步判断:某个请求在 worker 里死循环或密集计算。
命令:
bash# 查进程
top -H -p <nginx_pid>
# 找到 CPU 最高的线程 ID(十进制)
# 转十六进制
printf'%x\n' <tid>
# 看 perf
perf top -p <nginx_pid>
# 看 strace
strace -p <nginx_pid>
# 看 nginx 错误日志
tail -f /var/log/nginx/error.log
可能原因:
- 反代上游慢,但上游没死,导致大量连接堆积
try_files配合 deep nested 目录gzip大文件- Lua 代码死循环(OpenResty)
修复:
- 上游限流、加超时
- 减少
gzip启用范围 - 替换为异步框架
5.14 排障:大量 502/504
现象:accesslog 502/504 突增。
初步判断:Nginx 连不上后端或后端响应超时。
命令:
bash# 查后端状态
curl -v http://10.0.0.1:8080/health
# 看 nginx errorlog
tail -f /var/log/nginx/error.log
# 关键关键字:connect() failed (110: Connection timed out)
# upstream prematurely closed connection
# no live upstreams
# 看后端日志
ssh 10.0.0.1 'tail -n 200 -f /var/log/app/app.log'
# 看后端进程
ssh 10.0.0.1 'ps -ef | grep -E "java|node|python" | grep -v grep'
可能原因:
- 后端 OOM、重启中
- 后端慢导致超时
- 后端连接池满
- 网络丢包
修复:
- 加超时、加重试
- 后端扩容
- 检查网络
5.15 排障:磁盘写满
现象:df -h 看到 /var/log/nginx 占满。
命令:
bashdu -sh /var/log/nginx
ls -la /var/log/nginx/
可能原因:
- accesslog 太大
- errorlog 持续报错
- 没有 logrotate
修复:
- 临时:
truncate -s 0 /var/log/nginx/access.log; nginx -s reopen - 长期:logrotate + 定期归档
5.16 排障:连接打满
现象:ss -s 显示 ESTABLISHED 几十万个。
命令:
bashss -s
ss -tan 'sport = :80' | awk '{print $6}' | sort | uniq -c
# 看每个 IP 的连接数
ss -tan 'sport = :80' | awk 'NR>1 {print $6}' | sort | uniq -c | sort -nr | head
可能原因:
- 客户端未关闭长连接
- 爬虫 / 攻击
keepalive_timeout设得太大
修复:
- 减
keepalive_timeout - 减
keepalive_requests - 单 IP 限流
- IP 黑名单
5.17 平滑升级
操作目的:升级 Nginx 到新版本而不中断服务。
bash# 1. 备份
cp /usr/sbin/nginx /usr/sbin/nginx.bak
# 2. 编译新版本到临时目录
./configure --prefix=/tmp/nginx-new [options]
make
# 注意:不要 make install
# 3. 复制新 binary
cp /tmp/nginx-new/objs/nginx /usr/sbin/nginx.new
# 4. 替换
cp /usr/sbin/nginx.new /usr/sbin/nginx
# 5. 触发热升级
kill -USR2 $(cat /var/run/nginx.pid)
# 6. 等待
sleep 10
# 7. 优雅关闭旧 worker
kill -WINCH $(cat /var/run/nginx.pid.oldbin)
# 8. 关掉旧 master
kill -QUIT $(cat /var/run/nginx.pid.oldbin)
# 9. 验证
nginx -v
ps -ef | grep nginx
5.18 回滚配置
bash# 改之前先备份
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d_%H%M%S)
# 验证
nginx -t
# reload
nginx -s reload
# 出问题立刻回滚
cp /etc/nginx/nginx.conf.bak.YYYYMMDD_HHMMSS /etc/nginx/nginx.conf
nginx -t
nginx -s reload
5.19 WAF 集成
5.19.1 与 ModSecurity 集成
bash# 编译
./configure --add-module=/path/to/ModSecurity-nginx
make
make install
nginxmodsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
5.19.2 与云 WAF
通过 DNS 切换或 IP 回源切换到云 WAF。
5.19.3 自定义 WAF
nginxlocation / {
if ($request_method !~ ^(GET|POST|HEAD)$) { return 405; }
if ($http_user_agent ~* (sqlmap|nikto|acunetix|nmap)) { return 403; }
if ($query_string ~* union.*select) { return 403; }
if ($http_cookie ~* "(\.\./|\.\.\\)") { return 403; }
}
5.20 Kubernetes Ingress
使用 nginx-ingress-controller:
bash# 安装
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx
Ingress 资源:
yamlapiVersion: networking.k8s.io/v1
kind:Ingress
metadata:
name:api
annotations:
nginx.ingress.kubernetes.io/proxy-body-size:"50m"
nginx.ingress.kubernetes.io/rate-limit:"100"
nginx.ingress.kubernetes.io/rate-limit-window:"1m"
nginx.ingress.kubernetes.io/limit-rps:"10"
spec:
ingressClassName:nginx
tls:
-hosts:
-api.example.com
secretName:example-tls
rules:
-host:api.example.com
http:
paths:
-path:/
pathType:Prefix
backend:
service:
name:api-service
port:
number:80
六、常用命令
6.1 启动与停止
bashnginx # 启动
nginx -t # 测试配置
nginx -T # 测试并打印完整配置
nginx -s reload # 重新加载配置
nginx -s reopen # 重新打开日志
nginx -s stop # 停止(SIGTERM)
nginx -s quit # 优雅停止(SIGQUIT)
nginx -V # 编译信息
nginx -v # 版本
nginx -h # 帮助
6.2 进程与端口
bashps -ef | grep nginx
pgrep -af nginx
ss -tlnp | grep -E ':80|:443'
lsof -i :80
6.3 配置检查
bash# 测试配置
nginx -t
nginx -t -c /etc/nginx/nginx.conf
# 查看最终生效配置
nginx -T | less
# 格式化输出
nginx -T 2>&1 | grep -E '^\s*#' | grep -v '^\s*#\s*$' | head -20
6.4 性能压测
bash# ab
ab -n 1000 -c 100 http://example.com/
ab -k -n 10000 -c 200 -H 'Connection: keep-alive' https://example.com/
# wrk
wrk -t4 -c200 -d30s http://example.com/
wrk -t4 -c200 -d30s -H 'Host: example.com' https://example.com/
# hey
hey -n 5000 -c 200 http://example.com/
# vegeta
echo"GET http://example.com/" | vegeta attack -duration=30s -rate=1000 | vegeta report -type=hist[0,50ms,100ms,200ms,500ms,1s,2s,5s]
# 自带 stub_status
curl http://127.0.0.1/nginx_status
6.5 日志分析
bash# 状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
# 耗时 Top 20
awk '{print $NF, $0}' /var/log/nginx/access.log | sort -nr | head -20
# 5xx 错误
awk '$9 ~ /^5/' /var/log/nginx/access.log
# 客户端 IP 分布
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
# UA 分布
awk -F'"''{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
# URL Top 20
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
# 实时观察
tail -f /var/log/nginx/access.log | awk '{print $1, $9, $7, $NF}'
6.6 故障定位
bash# 看错误日志
tail -f /var/log/nginx/error.log
# 看连接
ss -tan 'sport = :80' | wc -l
# 看每个 worker 状态
curl http://127.0.0.1/nginx_status
# 看 CPU
top -H -p $(pgrep -f 'nginx: worker' | head -1)
# 看网络
ss -s
netstat -s
6.7 配置热加载
bashnginx -t && nginx -s reload
# 如果出错,自动回滚到上次成功的配置不会发生
# 一定要先 nginx -t 验证
6.8 升级与回滚
bash# 升级
kill -USR2 <master_pid>
sleep 10
kill -WINCH <old_master_pid>
kill -QUIT <old_master_pid>
# 回滚
kill -HUP <old_master_pid>
七、配置示例
7.1 静态资源服务器
nginxserver {
listen80;
server_name static.example.com;
root /data/www/static;
index index.html;
charset utf-8;
access_log /var/log/nginx/static.access.log;
location / {
try_files$uri$uri/ =404;
}
location~* \.(gif|jpg|jpeg|png|webp|avif|svg|ico)$ {
expires30d;
add_header Cache-Control "public, immutable";
access_logoff;
}
location~* \.(css|js|woff2?|ttf|eot)$ {
expires7d;
access_logoff;
}
location~* \.(mp4|webm|m4a|m4v|mov)$ {
mp4;
mp4_buffer_size4m;
mp4_max_buffer_size10m;
}
}
7.2 HTTPS + 反向代理
nginxupstream backend {
least_conn;
server10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server10.0.0.3:8080 max_fails=3 fail_timeout=30s;
keepalive64;
}
server {
listen80;
server_name api.example.com;
return301 https://$host$request_uri;
}
server {
listen443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;
access_log /var/log/nginx/api.access.log main;
error_log /var/log/nginx/api.error.log warn;
client_max_body_size50m;
location /health {
access_logoff;
return200'OK';
}
location / {
proxy_pass http://backend;
include /etc/nginx/snippets/proxy-params.conf;
}
}
7.3 限流配置
nginxhttp {
limit_req_zone$binary_remote_addr zone=perip:10m rate=10r/s;
limit_req_zone$server_name zone=perserver:10m rate=1000r/s;
limit_conn_zone$binary_remote_addr zone=perip_conn:10m;
server {
listen80;
server_name app.example.com;
location / {
limit_req zone=perserver burst=2000 nodelay;
limit_conn perip_conn 50;
proxy_pass http://backend;
}
location /api/login {
limit_req zone=perip burst=5 nodelay;
limit_req_status429;
add_header Retry-After 5s;
proxy_pass http://backend;
}
}
}
7.4 防盗链
nginxserver {
listen80;
server_name cdn.example.com;
root /data/www/cdn;
location~* \.(jpg|jpeg|png|gif|webp|avif)$ {
valid_referersnoneblocked example.com *.example.com;
if ($invalid_referer) {
return403;
}
expires30d;
add_header Cache-Control "public, immutable";
}
}
7.5 灰度发布
nginxupstream backend_v1 {
server10.0.0.1:8080;
server10.0.0.2:8080;
}
upstream backend_v2 {
server10.0.0.3:8080;
}
server {
listen80;
server_name app.example.com;
# 按 cookie 灰度
if ($cookie_gray = "v2") {
proxy_pass http://backend_v2;
break;
}
# 按 IP 灰度
set$gray0;
if ($remote_addr~ "^10\.0\.0\.[0-9]+$") {
set$gray1;
}
if ($arg_gray = "v2") {
set$gray1;
}
if ($gray = 1) {
proxy_pass http://backend_v2;
}
# 默认 v1
location / {
proxy_pass http://backend_v1;
include /etc/nginx/snippets/proxy-params.conf;
}
}
7.6 TCP/UDP 负载均衡
nginxstream {
log_format stream_log '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr"';
access_log /var/log/nginx/stream.access.log stream_log;
upstream mysql {
server10.0.0.1:3306 max_fails=3 fail_timeout=30s;
server10.0.0.2:3306 max_fails=3 fail_timeout=30s;
}
server {
listen3306;
proxy_pass mysql;
proxy_connect_timeout5s;
proxy_timeout600s;
}
upstream dns_backend {
server8.8.8.8:53;
server1.1.1.1:53;
}
server {
listen53 udp;
proxy_pass dns_backend;
proxy_timeout5s;
}
}
八、日志或指标观察方法
8.1 accesslog 格式
默认 combined 格式:
text192.168.1.10 - - [29/Jun/2026:10:23:45 +0800] "GET /api/user/1 HTTP/1.1" 200 1234 "-" "Mozilla/5.0 ..."
字段含义:
$remote_addr:客户端 IP$remote_user:HTTP 认证用户[$time_local]:本地时间"$request":请求行$status:响应码$body_bytes_sent:响应字节数"$http_referer":Referer"$http_user_agent":User-Agent
自定义字段:
$request_time:请求总耗时$upstream_response_time:上游响应耗时$upstream_addr:上游地址$upstream_status:上游状态$upstream_connect_time:上游连接耗时$upstream_header_time:上游响应头耗时$connection:连接序号$connection_requests:连接上的请求数$pipe:是否 pipeline$scheme:HTTP/HTTPS$request_id:请求唯一 ID
8.2 errorlog 关键错误
| 关键字 | 含义 | 处理建议 |
|---|---|---|
connect() failed (110: Connection timed out) | 上游连接超时 | 排查网络或上游 |
connect() failed (111: Connection refused) | 上游拒绝 | 上游未启动 |
upstream prematurely closed connection | 上游断连 | 上游崩溃或主动断 |
no live upstreams | 所有 upstream down | 检查 upstream 状态 |
client sent invalid header line | 客户端发非法头 | 客户端 bug 或攻击 |
client sent too large entity | 请求体过大 | 调大 client_max_body_size |
SSL_CTX_use_PrivateKey_file() failed | 私钥文件有问题 | 检查证书 |
BIO_new_file() failed | 证书文件读取失败 | 检查路径权限 |
worker process exited on signal 9 | worker 被 SIGKILL | OOM Killer 触发 |
worker process is shutting down | 优雅退出中 | 正常 |
an upstream response is buffered to a temporary file | 响应缓冲到磁盘 | 加 proxy buffer |
8.3 关键指标
| 指标 | 来源 | 健康范围 | 异常表现 |
|---|---|---|---|
| Active connections | stub_status | < worker_connections × workers | 持续 > 80% |
| Reading | stub_status | < 100 | > 500 表示 worker 处理慢 |
| Writing | stub_status | < 100 | > 500 表示上游写慢 |
| Waiting | stub_status | < 1000 | 持续 > 1 万为连接打满 |
nginx_http_requests_total | exporter | 业务相关 | 突增为流量暴涨 |
nginx_http_connections{state="active"} | exporter | < workers × connections | 持续高 |
nginx_upstream_response_time_seconds | vts | 业务相关 | 突增为上游慢 |
nginx_upstream_response_status | vts | 业务相关 | 5xx 突增 |
nginx_server_response_time_seconds | vts | 业务相关 | 突增 |
8.4 连接数计算公式
- 单 worker 最大并发连接:
worker_connections - 单 worker 上游连接:每反代一个客户端连接,就建立一个上游连接
- 系统总连接数:客户端 + 上游 + 文件描述符 <
ulimit -n - Linux ulimit 默认 1024,生产必须调高到 65535
调高:
bash# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
bash# systemd 单元
[Service]
LimitNOFILE=65535
LimitNPROC=65535
九、排查路径
9.1 502 Bad Gateway
- 看 upstream 状态
- 看
upstream_addr、upstream_status、upstream_response_time - 看
connect() failed还是upstream prematurely closed - 看后端日志
- 排查网络:
mtr、tcpping、curl -v
9.2 504 Gateway Timeout
- 看
proxy_read_timeout是否合理 - 看后端是否慢
- 抓后端 thread dump
9.3 413 Request Entity Too Large
- 调大
client_max_body_size - 检查 CDN 是否有大小限制
- 检查 Tomcat Spring
server.tomcat.max-http-form-post-size
9.4 499 Client Closed Request
- 客户端主动断开
- 后端慢导致客户端放弃
- 调后端或加缓存
9.5 403 Forbidden
allow/deny规则误伤auth_basic配置问题secure_link时间戳过期
9.6 404 Not Found
root/alias路径错try_files不匹配location优先级问题
9.7 400 Bad Request
- Header 过大
- 请求行过长
large_client_header_buffers调大
9.8 SSL 握手失败
- 证书链不全
- 协议版本不匹配
- 加密套件不匹配
9.9 worker 不断重启
worker_rlimit_nofile超限- 内存溢出
accept_mutex死锁error_log看具体错误
十、风险提醒
nginx -s reload前必须nginx -t,配置错误 reload 后 master 仍能接收连接,但 worker 不会接新连接,造成表面正常实际不服务client_max_body_size不设或过大会被攻击者发大文件耗尽磁盘worker_connections设得过大但ulimit -n没调高,worker 启动就报错keepalive_timeout设得过大会让攻击者占满长连接- 暴露
stub_status到公网会泄露内部状态 if指令在 location 块内使用有“邪恶 if”陷阱,能用map或set就别用if- 错误的
proxy_set_header Connection ""会让上游不保持长连接 proxy_buffering off会让上游响应立刻发到客户端,但同时占更多内存- 把
try_files配错成$uri/ =404之前的部分,会让所有请求落空 autoindex on会让目录可遍历,泄露信息geo模块加载超过 7 万条记录会启动失败gzip_types写错 MIME 会被攻击者上传非法格式文件add_header在if内只对当前if生效,redirect 中丢失头worker_rlimit_nofile必须小于ulimit -n
十一、验证方式
11.1 配置正确性
bashnginx -t
nginx -T | less
11.2 启动验证
bashsystemctl status nginx
ss -tlnp | grep -E ':80|:443'
curl -I http://localhost/
11.3 HTTPS 验证
bashcurl -vI https://example.com
openssl s_client -connect example.com:443 -servername example.com </dev/null
nmap --script ssl-enum-ciphers -p 443 example.com
11.4 性能验证
bashwrk -t4 -c200 -d30s http://localhost/
ab -n 1000 -c 100 http://localhost/
11.5 监控验证
bashcurl http://127.0.0.1/nginx_status
curl http://127.0.0.1:9113/metrics
11.6 日志验证
bashtail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
十二、回滚方案
12.1 配置回滚
bash# 修改前备份
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%Y%m%d_%H%M%S)
cp -r /etc/nginx/conf.d /etc/nginx/conf.d.bak.$(date +%Y%m%d_%H%M%S)
# 出问题立刻回滚
cp /etc/nginx/nginx.conf.bak.YYYYMMDD_HHMMSS /etc/nginx/nginx.conf
nginx -t
nginx -s reload
12.2 二进制回滚
bash# 保留 nginx.bak
kill -QUIT $(cat /var/run/nginx.pid)
cp /usr/sbin/nginx.bak /usr/sbin/nginx
systemctl start nginx
12.3 配置版本管理
bash# 用 git 管理
cd /etc/nginx
git init
git add .
git commit -m "init"
git log
git diff HEAD~1
# 出问题
git checkout HEAD~1
nginx -t
nginx -s reload
十三、生产环境注意事项
- 关闭
server_tokens - 关闭
autoindex - 关闭
ssi - 必须用 HTTPS
- 必须配置
Strict-Transport-Security - 必须配置
client_max_body_size上限 - 必须配置
worker_rlimit_nofile - 必须调高 systemd 单元的
LimitNOFILE - 必须配置
access_log与error_log - 必须 logrotate
- 必须配置
stub_status或 vts 给监控 - 必须配置 Prometheus exporter
- 必须配置告警(连接数、5xx 比例、上游响应时间、QPS 异常)
- 必须配置灰度
- 必须有回滚方案
- 必须做压测与基线
- 必须用非 root 用户启动
- 必须设置 systemd
Restart=always - 必须配置
LimitCORE=infinity用于 core dump - 必须配置
WorkingDirectory与RuntimeDirectory
十四、总结
Nginx 看似简单,做深了要懂 11 件事:
- 架构与信号
- 配置结构与变量
- 模块体系与编译参数
- 反向代理与负载均衡
- HTTPS 与 TLS
- 限流与防 CC
- 日志与监控
- 性能调优
- 高可用
- 平滑升级
- 典型排障
合格运维的标准,是把上面 11 件事都能在生产环境用 30 分钟内完成:
- 写出配置 5 分钟
- 排障 10 分钟
- 升级 5 分钟
- 回滚 5 分钟
- 留文档 5 分钟
剩下的是熟练度问题。
最后留一个清单,按这个清单自己跑一遍,能跑通就基本合格:
- 5 分钟写出一个 HTTPS + 反代 + 限流 + accesslog + 健康检查的 server 块
- 5 分钟写出 stub_status 监控 + Prometheus 集成
- 10 分钟完成一次 reload → 5xx 突增 → 抓 accesslog → 抓 errorlog → 回滚
- 5 分钟完成一次热升级
- 5 分钟压测 wrk 单 worker 5 万 QPS
如果都做不到,绕回来看文章。

本文链接:https://www.yunweipai.com/49310.html





网友评论comments