跳到主要内容
方的代码随记
返回

Nginx 性能优化

更新于:

1. 编译安装过程优化

减小编译产物体积

Nginx 默认以 debug 模式编译,会插入大量跟踪与 ASSERT 信息,产物有好几兆。取消 debug 后只有几百 KB。

解压源码后,编辑 auto/cc/gcc,找到并注释掉:

# debug
CFLAGS="$CFLAGS -g"

针对 CPU 做编译优化

默认 GCC 参数是 -O,可改为:

--with-cc-opt='-O3'
--with-cpu-opt=CPU

--with-cpu-opt 的有效值:pentium、pentiumpro、pentium3、pentium4、athlon、opteron、amd64、sparc32、sparc64、ppc64。

查看 CPU 类型:

cat /proc/cpuinfo | grep "model name"

2. 用 TCMalloc 优化内存分配

TCMalloc(Thread-Caching Malloc)来自 Google 的 google-perftools,内存分配效率和速度远高于 glibc 的 malloc,能显著提升高并发下的性能。

安装 libunwind(64 位系统需要)

cd /usr/local/src
wget https://download.savannah.gnu.org/releases/libunwind/libunwind-1.6.2.tar.gz
tar -zxvf libunwind-1.6.2.tar.gz
cd libunwind-1.6.2/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

CentOS 上编译如遇 stdatomic.h: 没有那个文件或目录,是因为自带 gcc 版本过低,需先升级 gcc。

安装 google-perftools

cd /usr/local/src
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.10/gperftools-2.10.tar.gz
tar -zxvf gperftools-2.10.tar.gz
cd gperftools-2.10/
./configure
make && make install

64 位系统需先装 libunwind,并在 configure gperftools 时加 --enable-frame-pointers 参数。

让 Nginx 使用 TCMalloc

编译时加入:

./configure --with-google_perftools_module
make && make install

若 Nginx 在装 google-perftools 之前就已安装,需要考虑平滑升级或平滑重启,在 configure 时补上参数即可。

验证:worker_processes 设为 4 时会生成 4 个线程记录,每个线程文件后面的数字就是该 Nginx 的 pid。

3. 内核参数优化

写入 /etc/sysctl.conf 后执行 /sbin/sysctl -p 生效:

net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 1
#net.core.somaxconn = 262144
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30

TCP 参数释义

参数说明
tcp_max_tw_bucketstimewait 数量上限,默认 180000,这里设 6000
ip_local_port_range允许系统打开的端口范围。Nginx 作代理时每个到上游的连接都要用一个临时端口,高并发下端口不够用
tcp_tw_recycle启用 timewait 快速回收
tcp_tw_reuse允许将 TIME-WAIT sockets 重用于新连接
tcp_syncookiesSYN 等待队列溢出时启用 cookies 处理
tcp_max_orphans最多允许多少 TCP 套接字不关联到用户文件句柄,防止简单 DoS
tcp_max_syn_backlog未收到客户端确认的连接请求最大值,128MB 内存系统默认 1024
tcp_synack_retries内核放弃连接前发送 SYN+ACK 包的数量
tcp_syn_retries内核放弃建立连接前发送 SYN 包的数量
tcp_fin_timeout套接字保持在 FIN-WAIT-2 状态的时间,默认 60 秒
tcp_keepalive_timekeepalive 启用时发送 keepalive 消息的频度,默认 2 小时

tcp_fin_timeout 值得注意:负载很小的 Web 服务器也可能因大量死套接字导致内存溢出。FIN-WAIT-2 危险性比 FIN-WAIT-1 小(最多消耗 1.5KB 内存),但生存期更长。

缓冲区队列

参数说明
net.core.somaxconn调节系统同时发起的 TCP 连接数,默认 128。高并发下默认值会导致链接超时或重传;若设置大于 512,需同步调整 Nginx listen 指令的 backlog 参数
net.core.netdev_max_backlog网络接口收包速率快于内核处理速率时,允许发送到队列的数据包最大数目

4. PHP-FPM 优化

高负载站点用 PHP-FPM 管理 FastCGI 时:

  1. 增加 FastCGI 进程数:PHP FastCGI 子进程数调到 100 以上,4G 内存的服务器上 200 即可,建议用压力测试获取最佳值;
  2. 增加 PHP-FPM 打开文件描述符的限制:在 php-fpm 启动脚本或服务文件中提高 ulimit -n,并与 worker_rlimit_nofile 对齐。
pm = dynamic
pm.max_children = 200
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
rlimit_files = 65536

5. nginx.conf 参数优化

指令建议
worker_processes设为 CPU 核心数或 auto
worker_cpu_affinity多核机器可绑定 CPU,减少进程切换开销
worker_rlimit_nofile与 ulimit -n 一致,避免并发高时返回 502
worker_connections尽量大,最大并发 ≈ worker_processes × worker_connections
use epollLinux 2.6+ 用 epoll 事件模型
sendfile on开启零拷贝传输
tcp_nopush / tcp_nodelay配合 sendfile 开启
gzip on开启压缩,注意 gzip_comp_level 不宜过高
keepalive_timeout长连接超时,按业务调整,过长会占用连接资源
open_file_cache缓存打开的文件描述符,减少 stat 调用

优化顺序建议

  1. 先确认瓶颈在哪:CPU 密集、IO 密集还是连接数打满;
  2. 编译期优化收益有限,优先调 worker_* 与内核参数;
  3. 每次只改一处并用压测对比,避免参数堆叠掩盖真实问题;
  4. somaxconn 与 listen ... backlog、worker_rlimit_nofile 与 ulimit -n 这两对参数必须成对调整。

分享这篇文章:

上一篇
Nginx 实用配置片段
下一篇
CentOS / Ubuntu 搭建 Nginx