Nginx 性能调优

Nginx 本身很快,但默认参数偏保守。本章从 worker 数量、连接数、零拷贝、keepalive、静态缓存与 gzip 入手,方向对了往往几行配置就能明显提升吞吐。

worker 进程与连接数

worker_processes 一般取 CPU 核心数,写 auto 让 Nginx 自动探测;每个 worker 的并发上限是 worker_connections,同时受系统文件描述符限制(ulimit -n):

worker_processes auto;             # 通常 = CPU 核心数
worker_cpu_affinity auto;          # 自动把 worker 绑定到不同 CPU

events {
    worker_connections 4096;       # 单 worker 最大并发连接
    use epoll;                     # Linux 推荐的事件模型
    multi_accept on;               # 一次事件循环尽量接受多个新连接
}

最大并发约等于 worker_processes × worker_connections,记得同步调大系统 ulimit:

ulimit -n 65535    # 会话级生效;永久修改写入 /etc/security/limits.conf

keepalive 与零拷贝

keepalive 让同一客户端复用连接,静态站收益明显;sendfile 把文件从磁盘零拷贝直发网卡,配合 tcp_nopush/tcp_nodelay 减少小包:

http {
    keepalive_timeout 65;            # 长连接超时时间
    keepalive_requests 1000;         # 单条连接最多复用处理 1000 次请求
    sendfile on;                     # 零拷贝发送静态文件
    tcp_nopush on;                   # 攒够数据包再发送(需与 sendfile 配合)
    tcp_nodelay on;                  # 小响应不等待,降低延迟
}

静态文件缓存

open_file_cache 缓存文件描述符与元数据,省去重复 stat/open;静态资源再配 expires 让浏览器缓存:

http {
    open_file_cache max=4096 inactive=20s;    # 缓存 4096 个文件句柄,20s 无访问淘汰
    open_file_cache_valid 60s;                # 每 60s 校验一次缓存是否过期
    open_file_cache_min_uses 2;               # 被访问 2 次以上才缓存

    server {
        location ~* \.(css|js|png|jpg|svg|woff2)$ {
            expires 7d;                       # 浏览器缓存 7 天
            add_header Cache-Control "public";
        }
    }
}

gzip 与日志 IO

文本资源开 gzip 可省一半以上流量(详见 gzip 章节);日志写入是隐藏的磁盘 IO 大户,开 buffer 合并写盘,高频探活接口直接关日志:

http {
    gzip on;
    gzip_types text/plain text/css application/javascript application/json;
    gzip_min_length 1k;

    access_log /var/log/nginx/access.log combined buffer=32k flush=5s;
    # 对纯静态或探活 location 可 access_log off;
}

系统层(一句话带过)

把文件描述符上限(ulimit -n)、内核 TCP 队列 net.core.somaxconn、net.ipv4.tcp_tw_reuse 等调大通常能再挤出一部分性能;改 sysctl 前务必先压测留好基线,避免盲目调参。

小结

调优主线:worker 数对齐 CPU、worker_connections 受 ulimit 约束、sendfile/keepalive 降开销、open_file_cache + expires 减磁盘与网络、gzip 与 access_log buffer 省流量与 IO。改一处、压测一处,别一次性全上。

笔记加载中…