nginx性能优化专题整理
转载请备注来源: 《nginx性能优化专题整理》 | shuwoom.com
摘要
本文主要介绍nginx性能优化的相关知识,系统梳理从内核参数优化、Nginx配置优化到缓存优化以及负载均衡架构设计。由点到面再到整体来系统介绍nginx性能优化的方方面面知识。
sysctl.conf操作
查看系统参数:
sysctl -a
查看tcp网络相关的系统参数
sysctl -a|grep net.ipv4.tcp
启用最新系统参数
sysctl -p
内核参数优化
Linux内核参数默认考虑的是最通用的场景,但是在高并发的web服务器上,这个不太适用。所以,我们需要根据实际的业务特点来进行调整,提高Nginx的并发性能。如下是几个比较关键的参数。我们可以通过修改/etc/sysctl.conf来修改内核参数。
增大套接字读写缓存
- 读缓冲区,缓存了远端发送过来的数据。如果读缓冲区已满,就不能再接收新的数据
- 写缓冲区,缓存了要发出去的数据。如果缓冲区已满,应用程序的写操作就会阻塞
所以,为了提高网络的吞吐量,通常要调整这些缓冲区大小。
备注:下图转载自《Linux性能优化实战》

TCP配置优化
数值仅提供参考,具体配置请结合实际场景来调整。
tcp_max_tw_buckets
这个参数表示操作系统允许TIME_WAIT套接字数量的较大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。
net.ipv4.tcp_max_tw_buckets = 5000
tcp_fin_timeout
当服务器主动关闭链接时,socket保持在FIN_WAIT_2状态的较大时间
net.ipv4.tcp_fin_timeout = 30
tcp_tw_reuse
开启重用功能,允许将TIME-WAIT状态的sockets重新用于新的TCP链接。设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接,这意味着服务器总会有大量的TIME_WAIT状态的连接存在。
net.ipv4.tcp_tw_reuse = 1
ip_local_port_range
定义UDP和TCP链接的本地端口取值范围。调高系统的IP以及端口数据限制,从而可以接受更多的连接。
net.ipv4.ip_local_port_range = 1024 65000
tcp_max_syn_backlog
这个参数表示TCP三次握手建立阶段接受SYN请求列队的较大长度,默认1024,将其设置的大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的链接请求。
net.ipv4.tcp_max_syn_backlog = 8192
tcp_syncookies
与性能无关,用于解决TCP的SYN攻击。
net.ipv4.tcp_syncookies = 1
tcp_keepalive_time
当keepalive启动时,TCP发送keepalive消息的频度,用于确认TCP连接是否有效;默认是2小时,将其设置为10分钟,可以更快的清理无效链接。
ner.ipv4.tcp_keepalive_time = 600
更多跟TCP优化相关的参数,如下表所示:
备注:下图转载自《Linux性能优化实战》

NGINX配置文件优化
异步I/O(thread_pool)
thread_pool的使用方法见我写的文章《Nginx配置文件(nginx.conf)详解》。异步I/O允许进程进行不受阻塞或不需等待I/O完成的I/O操作。那么,我们在什么情况下可以使用这个配置项呢?
我们知道,Nginx是基于事件模型的异步服务器,但是对于阻塞事件的处理,会导致后面其他网络事件处理被迫延时。如下图所示,后面的事件需要等待前面的阻塞事件(文件读写、耗时的数据库操作)处理完后才可以进入处理。

未启用thread_pool时,Nginx事件处理流程如下图所示:

而使用了thread_pool后,其处理流程编程如下:

这时候Nginx就多了一个任务队列和线程池。当出现一个阻塞的事件时,nginx会把它丢到任务队列中,然后继续处理下一个事件。这样每个事件的处理就不会因为某个阻塞事件而导致整体被延误。
关于这个参数的详细细节,可以阅读国外网友写的一篇文章:https://www.nginx.com/blog/thread-pools-boost-performance-9x/
例如:
thread_pool one threads=128 max_queue=0; thread_pool two threads=32; http { server { location /one { aio threads=one; } location /two { aio threads=two; } } … }
worker_process
nginx进程数,建议按照cpu的数目来指定,一般是相等。如8核cupu:
worker_process 8;
worker_cpu_affinity
为每个进程分配cpu,上例中将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
或者直接适用auto选项,让nginx自动绑定可用的cpu核。
worker_cpu_affinity auto;
worker_rlimit_nofile
这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。
worker_rlimit_nofile 102400;
sendfile
当应用程序传输文件时,内核首先缓冲数据,然后将数据发送到应用程序缓冲区。应用程序最后将数据发送到目的地。
sendfile方法则是对输出传输方法进行改进,其中数据在操作系统内核空间内的文件描述符之间复制,而不将数据传输到应用程序缓冲区,这样极大提高了系统资源的利用率。使用详细参数和方法见:《Nginx配置文件(nginx.conf)详解》](https://shuwoom.com/?p=4292)。
http { sendfile on; }
epoll
使用epoll的I/O模型
use epoll;
worker_connections
每个进程允许的最大连接数,理论上每台nginx服务器的最大连接数为worker_process*worker_connections。
worker_connections 102400;
keepalive_timeout
keepalive超时时间。
keepalive_timeout 60;
client_header_buffer_size
客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
client_header_buffer_size 4k;
open_file_cache_valid
这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid 30s;
open_file_cache_min_uses
这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1;
缓存的使用
详细的文章介绍可以参看我写的文章:《Nginx缓存机制详解》
负载均衡
详细的文章介绍可以参看我写的文章:NGINX负载均衡搭建
转载请备注来源: 《nginx性能优化专题整理》 | shuwoom.com