01. Worker 进程与连接数调优
Nginx 的高性能底座是它的事件驱动架构——一个 worker 进程能同时处理几千个连接,不像 Apache 每个连接一个进程/线程。
worker_processes——多少个 worker 进程。一般设成 CPU 核心数(auto 可以让 Nginx 自动检测)。设多了会有上下文切换开销,设少了浪费 CPU。
worker_connections——每个 worker 最多同时处理多少个连接。默认 512。生产环境至少 1024~4096。
最大并发连接数 = worker_processes * worker_connections。但还要除以 2(因为每个请求需要客户端和服务端两个连接,对于反向代理)才是实际并发请求数。
worker_rlimit_nofile——系统级别的文件描述符限制。必须大于 worker_connections(Nginx 每个连接要用 1~2 个文件描述符)。
nginx
# Nginx 核心性能配置
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll; # Linux 上的高效事件模型
multi_accept on; # 一次 accept 所有新连接
}
# 理论最大并发 = worker_processes * worker_connections / 2
# 4 核 * 4096 / 2 = 8192 个并发请求worker_connections 设置好后用 ulimit -n 确认系统的文件描述符限制大于这个值。不够的话需要改 /etc/security/limits.conf。
02. 静态资源缓存与 sendfile
Nginx 作为静态文件服务器的性能优化主要靠两点:内核级别的文件传输和缓存。
sendfile on——用操作系统的 sendfile 系统调用直接把文件从磁盘传到网络,不经过用户空间的内存拷贝。性能提升明显。
tcp_nopush on——跟 sendfile 配合,尽可能让 Nginx 在一个 TCP 包里发送完整的响应头加数据。
tcp_nodelay on——对小数据包不延迟直接发。跟 tcp_nopush 不冲突——前者优化大文件,后者优化小响应。
open_file_cache——把打开的文件描述符缓存起来,不用每次都 open/close。能存文件句柄、修改时间、大小等信息。静态文件多的时候收益明显。
nginx
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# 文件缓存
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# keepalive:长连接
gzip on;
keepalive_timeout 65;
keepalive_requests 100;open_file_cache 的 inactive 参数:如果一个文件在若干秒内没有被访问,它就从缓存里移除。缓存太大也会占内存。
03. 反向代理缓存
Nginx 不仅能代理请求,还能缓存后端返回的响应——经常访问的页面缓存起来,后端少处理很多请求。
proxy_cache_path 定义缓存目录、缓存大小、过期策略。proxy_cache 在 location 里开启缓存。
proxy_cache_key——用什么作为缓存的 key。默认是协议+域名+URI,一般够用。
proxy_cache_valid——不同 HTTP 状态码缓存多久。200 可以长一点,404 短一点。
proxy_cache_bypass——设置条件跳过缓存(如 cookie 里有特定值)。
注意:动态内容(每个用户看到不一样的)不要缓存,或者用 vary 头区分。缓存了用户个人信息就是安全事故。
nginx
# 在 http 块定义缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g inactive=60m;
# 在 location 使用
location /api/ {
proxy_cache mycache;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_bypass $cookie_nocache;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}$upstream_cache_status 变量能显示 HIT(命中缓存)或 MISS(没命中)或 BYPASS(跳过)。加到响应头里方便调试。
04. 负载均衡策略
Nginx upstream 模块支持多种负载均衡策略:
轮询(默认)——请求按顺序分配给后端。配合 weight 加权——性能好的机器设高权重。
least_conn——优先分配给连接数最少的后端。适合长连接场景(WebSocket)。
ip_hash——根据客户端 IP 的 hash 固定分配后端。同一个 IP 的请求永远到同一台机器。适合有状态的 session 场景(但不推荐依赖 session,最好用无状态设计)。
hash——自定义 key 做 hash(如 $request_uri),相同 key 请求固定到同一台机器。
健康检查:max_fails 和 fail_timeout——在 fail_timeout 时间内失败 max_fails 次就暂时剔除这个后端。
生产环境建议用云厂商的负载均衡(ALB/ELB)做四层分发,Nginx 做七层路由。
nginx
# 定义 upstream
upstream backend {
least_conn; # 最少连接策略
server 10.0.1.10:3000 weight=3 max_fails=2 fail_timeout=30s;
server 10.0.1.11:3000 weight=1;
server 10.0.1.12:3000 backup; # 备用,其他都挂了才用
}
# ip_hash 策略
upstream sticky_backend {
ip_hash;
server 10.0.1.10:3000;
server 10.0.1.11:3000;
}
location / {
proxy_pass http://backend;
}后端挂了 Nginx 不会一直等——proxy_connect_timeout、proxy_read_timeout 设置好超时时间,超时了就换下一个后端。
05. 性能监控与日志分析
Nginx 自带一个简单的状态监控页面(stub_status),能看到当前连接数、处理过的请求数。
开启 stub_status:用 stub_status 指令或 status 模块。看 Active connections、accepts(总连接数)、handled(处理成功的连接数)、requests(总请求数)。
Reading(正在读请求头)、Writing(正在发响应)、Waiting(keep-alive 等待中)。Waiting 多说明 keepalive 在工作,空闲连接多。Reading/Writing 多且持续增长说明有压力。
日志分析:用 GoAccess 或 awk 脚本分析 access.log,统计 QPS、响应时间分布、错误率。
专业监控:Prometheus + nginx-prometheus-exporter 把 Nginx 指标接入 Grafana,跟服务端的指标一起看。
nginx
# 开启 stub_status
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
# 访问后会输出:
# Active connections: 291
# server accepts handled requests
# 16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106
# 日志格式(加响应时间)
log_format timed '$remote_addr - [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log timed;nginx-prometheus-exporter 能导出 connect/request/time 等指标到 Prometheus。比 stub_status 强大太多,生产环境推荐。
知识测验
第 1/5 题正确 0
worker_connections 设置的是什么?
下一节
下一节 日志与监控