Nginx性能优化

Nginx性能优化应当遵循一个原则:一次只调整一项,若调整不能提提升性能,则将修改还原。

Linux参数

Nginx很多功能直接使用操作系统的实现,操作系统决定nginx上限。

现代Linux内核(2.6+)中涵盖了大多数应用场景,查看linux内核日志,找出参数过低的提示消息,根据建议进行调整。

连接队列

若传入连接速率很高,且性能水平参差不齐(如某些连接停滞不动),那么,更改如下设置会有所帮助,如下设置与连接和排队方式有关。

sudo sysctl -w net.core.somaxconn=4096

vim /etc/sysctl.conf:

net.core.somaxconn - 等待NGINX响应,排队所能接受的最大连接数
net.core.somaxconn = 4096

默认值通常很低,因为,通常nginx接受连接的速度非常快,但若网站流量很大则增加它。若内核日志中的错误消息指示该值太小,将其增加到错误提示不再出现。

若此值大于512,将backlog参数改为nginx listen指令以进行匹配,如下所示:

server {
    listen 80 backlog=4096;
    # ...
}

若带宽够大,增加如下参数可提升性能。

net.core.netdev_max_backlog - 在切换到CPU之前,网卡缓冲数据包的速率

检查内核日志,是否存在与此设置相关的错误提示,查阅网卡文档获取有关建议。

文件描述符

Nginx每个连接最多可使用两个文件描述符。

如,若nginx为代理通常使用一个文件描述符标识客户端连接,另一个则用于连接到后端服务器。若使用HTTP keepalive,比率会低很多。

对于有大量连接的系统,需要调整以下设置:

sys.fs.file-max 文件描述符的系统范围限制

查看

cat /proc/sys/fs/file-max

ulimit -u 查看进程限制数

ulimit -n 查看文件限制数

ulimit -a 查看系统所有资源限制。

修改限制

vi /etc/security/limits.conf

vi /etc/security/limits.d/90-nproc.conf

参数列表

root soft nproc unlimited
  * soft nproc 65535
  * hard nproc 65535
  * soft nofile 65535
  * hard nofile 65535

soft 软限制,hard硬限制。

当数量达到软限制时会报警,达到硬限制时将不再增加。

nproc: 单个用户可用的最大进程数量

nofile:可打开的文件描述符的最大值(软限制)。

注:更多详情查看ulimit

临时端口

Nginx充当代理时,与上游服务器的每个连接都会产生一个临时端口,可更改如下设置:

net.ipv4.ip_local_port_range - 端口值允许的范围

若发现端口不足扩大端口范围,常见端口设置从1024到65000。

NGINX参数

Nginx指令调整,只讨论安全且可自行调整的指令。

Worker进程调整

Nginx能够运行多个Worker进程,每个进程都能处理大量并发连接。

使用以下指令控制工作进程的数量,以及如何处理连接。

worker_processes

Nginx工作进程数量默认为1。

大多数情况下,一颗CPU核心运行一个工作进程效果比较好,建议将选项设置为auto。

有时可能希望增加此数值,如当工作进程必须执行大量磁盘I/O时。

worker_connections

每个工作进程可同时处理的最大连接数,默认值为512。

大多数系统都有足够的资源支持更大的值。适当的参数值,取决于服务器流量大小和流量性质,这些可通过测试得出。

Keepalive连接

减少打开/关闭连接所需的开销,Keepalive连接可能会对性能产生大影响。

Nginx支持客户端和上游服务器的Keepalive。

客户端Keepalive

keepalive_requests

客户端通过单个keepalive连接可发出的请求数,默认值为100。

更高的值可能需要借助负载生成工具测试。

keepalive_timeout

空闲keepalive连接保持打开状态的时间。

上游/upstream Keepalive

以下指令涉及上游(upstream )Keepalive。

keepalive

每个工作进程,与上游服务器的空闲keepalive连接数,无默认值。

启用与上游服务器的keepalive连接,须在配置中包含如下指令:

proxy_http_version 1.1;
proxy_set_header Connection "";

Nginx访问记录

记录每个请求消耗CPU和I/O周期,减少影响的一种方法是启用日志缓冲。

通过缓冲,nginx不再为每个条日志执行单独的写操作,缓冲一系列条目,一次将它们写入文件。

启用访问日志缓冲,需将参数包含在指令中。

当缓冲区达到阀值时,nginx将缓冲区内容写入磁盘日志。

也可让nginx在指定的时间后写入缓冲区,需在参数中指定时间。

设置这两项参数后,当下一条日志不适合缓冲区,或缓冲区中的条目超过指定时间,Nginx会将条目写入日志文件。

当工作进程重新打开日志文件或关闭时,会将日志写入磁盘。要完全禁用访问日志记录,则通过参数指定即可。

buffer=sizeaccess_logsizeflush=timeoffaccess_log

Sendfile

操作系统的sendfile()系统调用,将数据从一个文件描述符,复制到另一个文件描述符,实现零拷贝以此加速TCP数据传输。

要让nginx使用它,需在http context或server或location context中包含该指令。

location /mp3 {
    sendfile           on;
    sendfile_max_chunk 1m;
    #...
}

Nginx可在socket上写入缓存或磁盘内容,而无需任何上下文切换,使写入速度极快且占用CPU更少。

位置 / mp3  { 
    sendfile    on ; 
    tcp_nopush  on ; 
    #... 
}

nopush避免发送小数据包,等待数据包达到一定大小再发送。

location /mp3  {
    tcp_nodelay       on;
    keepalive_timeout 65;
    #...
}

tcp_nodelay期望数据尽快地发送 ,实际上可以联合使用,先填满包再尽快发送。

注:由于数据通过sendfile()绕过了用户空间,因此,不受常规nginx处理链和过滤器的限制,如gzip。当配置上下文即包含sendfile,又激活了内容修改过滤器,nginx会在上下文中自动禁用sendfile。

Nginx限制

设置各种限制防止客户端消耗太多资源,可能会对系统性能及安全性,和用户体验产生负面影响。以下是一些相关指令:

limit_conn

limit_conn_zone

从单个IP地址限制nginx接受客户端的连接数,此设置能防止个别客户端打开过多连接消耗资源。

limit_rate

限制每个连接将响应传输到客户端的速率(多个连接的客户端会消耗此带宽量)。

设置限制可防止系统被某些客户端过载,确保能为所有客户端提供均匀的服务。

limit_req

limit_req_zone

限制nginx请求率,与limit_rate异曲同工。可提高安全性,特别是对于登录页面,将请求率限制为合理值,降低试图通过请求压跨应用的恶意请求(如,DDoS中的僵尸程序)。

max_conns

server块中upstream指令的参数。

设置上游服务器能接受的最大并发连接数,此限制有助于防止上游服务器过载,将值设置为0(默认值)表示没有限制。

queue (NGINX Plus)

创建一个队列,当上游可用服务器达到max_conns限制时,将该队列中放置请求。此伪指令设置队列中的最大请求数,及在返回错误前等待的最长时间(默认60秒)。若省略该指令,则请求不会排队。

缓存和压缩

用于提高Web应用性能的一些附加功能,不属于真正的调优,之所以提到是因为,受它们影响的可能很大,如:缓存和压缩。

缓存

在负载均衡的nginx实例上启用缓存,可显著缩短响应时间,同时减少后端服务器的负载。缓存本身就是一个主题,所以,不作过多介绍。

压缩

压缩响应数据,可大大节省网络带宽。但同时也会消耗CPU资源。务必注意,不应对已压缩的对象(如JPEG文件)启用压缩。