Nginx配置优化,提高Nginx性能
本文不讨论操作系统方面的优化,只讨论在Nginx层面能进行如何优化,以达到尽可能最优的性能。也为了能应付高并发的网络大流量的情况。
worker_processes
worker_processes
用来设置Nginx服务的进程数。推荐是CPU内核数或者内核数的倍数,推荐使用CPU内核数
worker_cpu_affinity
默认情况下,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上,导致Nginx进程使用硬件的资源不均,因此绑定Nginx进程到不同的CPU上是为了充分利用硬件的多CPU多核资源的目的。
worker_cpu_affinity
用来为每个进程分配CPU的工作内核,参数有多个二进制值表示,每一组代表一个进程,每组中的每一位代表该进程使用CPU的情况,1代表使用,0代表不使用。所以我们使用worker_cpu_affinity 0001 0010 0100 1000
;来让进程分别绑定不同的核上。
worker_connections
默认的值是1024,设置一个进程理论允许的最大连接数,理论上越大越好,但不可以超过worker_rlimit_nofile
的值。
linux系统中有个指令open file resource limit
,它设置了进程可以打开的文件句柄数量,可以用下面的指令查看你的linux系统中open file resource limit
指令的值:
cat /proc/sys/fs/file-max
可以将该指令设置为23900251
worker_rlimit_nofile
设置毎个进程的最大文件打开数。如果不设的话上限就是系统的ulimit –n
的数字,一般为65535。
use epoll
Linux关键配置,允许单个线程处理多个客户端请求。
与apache类似,nginx针对不同的操作系统,有不同的事件模型:
- 标准事件模型
Select、poll
属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll - 高效事件模型
Kqueue
:使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。Epoll
: 使用于Linux内核2.6版本及以后的系统。
/dev/poll:使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。Eventport
:使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装安全补丁。
accept_mutex
当某一时刻只有一个网络连接到来时,多个睡眠进程会被同时叫醒,但只有一个进程可获得连接,如果每次唤醒的进程数目太多,会影响一部分系统性能。
在Nginx服务器的多进程下,就可能出现这个问题,为了解决这个问题,Nginx配置了包含这样一条指令accept_mutex
,当其设置为开启的时候,将会对多个Nginx进程接受连接进行序列化,防止多个进程对连接的争抢。当服务器连接数不多时,开启这个参数会让负载有一定程度的降低。但是当服务器的吞吐量很大时,为了效率,请关闭这个参数;并且关闭这个参数的时候也可以让请求在多个worker间的分配更均衡。所以我们设置accept_mutex off
;
multi_accept
告诉nginx收到一个新连接通知后接受尽可能多的连接,设置为on
sendfile
开启sendfile
选项,使用内核的FD文件传输功能,这个比在用户态用read() + write()
的方式更加高效。普通应用应该设为on,下载等IO重负荷的应用应该设为off,因为大文件不适合放到buffer
中。
tcp_nopush
sendfile
为on时这里也应该设为on,数据包会累积一下再一起传输,可以提高一些传输效率。
tcp_nodelay
小的数据包不等待直接传输。默认为on。
看上去是和tcp_nopush
相反的功能,但是两边都为on时nginx也可以平衡这两个功能的使用。
keepalive_timeout
配置连接keep-alive
超时时间,服务器将在超时之后关闭相应的连接,设的太长会使无用的线程变的太多。这个根据自己服务器访问数量、处理速度以及网络状况方面考虑,10-30
之间即可。
send_timeout
设置Nginx服务器响应客户端的超时时间,这个超时时间只针对两个客户端和服务器建立连接后,某次活动之间的时间,如果这个时间后,客户端没有任何活动,Nginx服务器将关闭连接,将其设置为10s,Nginx与客户端建立连接后,某次会话中服务器等待客户端响应超过10s,就会自动关闭。,默认是 60 秒。
types_hash_max_size
types_hash_max_size
影响散列表的冲突率。types_hash_max_size
越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。types_hash_max_size
越小,消耗的内存就越小,但散列key的冲突率可能上升。
client_header_buffer_size
客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
分页大小可以用命令getconf PAGESIZE
取得,可以将其设置为4k;
client_max_body_size 8m
客户端上传的body的最大值。超过最大值就会发生413(Request Entity Too Large)错误。默认为1m,最好根据自己的情况改大一点。
gzip
启用gzip
,对响应数据进行在线实时压缩,减少数据传输量。
gzip_disable
Nginx服务器在响应这些种类的客户端请求时,不使用Gzip功能缓存应用数据,gzip_disable
"msie6"对IE6浏览器的数据不进行GZIP压缩。
gzip_min_length
Gzip压缩功能对大数据的压缩效果明显,但是如果压缩很小的数据,可能出现越压缩数据量越大的情况,因此应该根据相应页面的大小,选择性开启或者关闭Gzip功能,建议将值设置为1KB。
gzip_comp_level
设置压缩程度,包括级别1到级别9,级别1表示压缩程度最低,压缩效率最高;级别9表示压缩程度最高,压缩效率最低,最费时间。设置为3-4即可。
gzip_vary
用于设置在使用Gzip功能时是否发送带有“Vary:Accept-Encoding”
头域的响应头部,该头域的主要功能是告诉接收方发送的数据经过了压缩处理,开启后端效果是在响应头部Accept-Encoding: gzip
,对于本身不支持Gzip的压缩的客户端浏览器是有用的。
gzip_buffers
该指令用于设置Gzip压缩文件使用存储空间的大小,
语法gzip_buffers number size。number
指定Nginx服务器需要向系统申请存储空间的个数,size
指定每个缓存空间的大小。根据配置项,Nginx服务器在对响应输出数据进行Gzip压缩时需向系统申请number,size
大小的空间用于存储压缩数据。
gunzip_static
开启时,如果客户端浏览器不支持Gzip处理,Nginx服务器将返回解压后的数据,如果客户端浏览器支持Gzip处理,Nginx服务器忽略该指令设置。仍然返回压缩数据。
gzip_types
Nginx服务器可以根据MIME类型选择性开启Gzip压缩功能。该指令涌来设置MIME类型。
access logs
默认情况下,Nginx的每个请求都会记录在磁盘上的日志文件中,你可以使用这个方法进行统计,安全问题检查等, 带着这会在一定程度上带来IO使用成本. 如果你不打算用这些访问日志来做一些检查或其他用途, 你可以直接关闭它以避免对磁盘写操作, 但是如果你需要访问日志,你可以考虑保存日志到内存中.这将会比直接写到磁盘上快很多,并且明显减少IO的使用.
error logs
错误日志的等级参数你是可以指定的, 如果你指定的太低了他会记录404错误甚至是debug信息. 在实际的应用中可以将它设置为warn级别,将会是绰绰有余的并且能降低IO.
error_log /var/log/nginx/error.log crit;
告诉nginx只能记录严重的错误:
open file cache
从文件系统中读取文件由2部分组成,打开和关闭文件. 考虑到这是一个有阻塞的操作,因此不要忽略这部分. 因此, 对于我们来说缓存打开文件的描述符是非常好的
client_body_buffer_size
client_body_buffer_size
指令用来指定处理客户端请求的缓冲区大小,?这个代表了访问请求的body. 这是用来处理POST的数据,也就是通过提交表单,文件上传等请求的数据. 如果你需要处理很多大的POST请求的,你必须确保缓存区要设置的足够大.
proxy_buffers
proxy_buffers的缓冲区大小一般会设置的比较大,以应付大网页。 proxy_buffers当中单个缓冲区的大小是由系统的内存页面大小决定的,Linux系统中一般为4k。 proxy_buffers由缓冲区数量和缓冲区大小组成的。总的大小为number*size。
若某些请求的响应过大,则超过_buffers的部分将被缓冲到硬盘(缓冲目录由_temp_path指令指定), 当然这将会使读取响应的速度减慢, 影响用户体验. 可以使用proxy_max_temp_file_size指令关闭磁盘缓冲.
proxy_buffer_size
后端服务器的相应头会放到proxy_buffer_size
当中,这个大小默认等于proxy_buffers
当中的设置单个缓冲区的大小。 proxy_buffer_size
只是响应头的缓冲区,没有必要也跟着设置太大。 proxy_buffer_size
最好单独设置,一般设置个4k就够了。
proxy_busy_buffers_size
proxy_busy_buffers_size
不是独立的空间,他是proxy_buffers
和proxy_buffer_size
的一部分。nginx会在没有完全读完后端响应的时候就开始向客户端传送数据,所以它会划出一部分缓冲区来专门向客户端传送数据(这部分的大小是由proxy_busy_buffers_size
来控制的,建议为proxy_buffers
中单个缓冲区大小的2倍),然后它继续从后端取数据,缓冲区满了之后就写到磁盘的临时文件中。
proxy_max_temp_file_size proxy_temp_file_write_size
临时文件由proxy_max_temp_file_size和proxy_temp_file_write_size这两个指令决定。 proxy_temp_file_write_size是一次访问能写入的临时文件的大小,默认是proxy_buffer_size和proxy_buffers中设置的缓冲区大小的2倍,Linux下一般是8k。
proxy_max_temp_file_size指定当响应内容大于proxy_buffers指定的缓冲区时, 写入硬盘的临时文件的大小. 如果超过了这个值, Nginx将与Proxy服务器同步的传递内容, 而不再缓冲到硬盘. 设置为0时, 则直接关闭硬盘缓冲.
proxy_buffering
proxy_buffering
这个参数用来控制是否打开后端响应内容的缓冲区,如果这个设置为off,那么proxy_buffers
和proxy_busy_buffers_size
这两个指令将会失效。 但是无论proxy_buffering
是否开启,对proxy_buffer_size
都是生效的。
proxy_buffering
开启的情况下,nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端(边收边传,不是全部接收完再传给客户端)。 临时文件由proxy_max_temp_file_size
和proxy_temp_file_write_size
这两个指令决定的。
如果proxy_buffering关闭,那么nginx会立即把从后端收到的响应内容传送给客户端,每次取的大小为proxy_buffer_size的大小,这样效率肯定会比较低。
注: proxy_buffering启用时,要提防使用的代理缓冲区太大。这可能会吃掉你的内存,限制代理能够支持的最大并发连接数。
server_tokens
server_tokens off;
并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
client_header_timeout client_body_timeout
设置请求头和请求体(各自)的超时时间。我们也可以把这个设置低些。
reset_timeout_connection
告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
limit_conn_zone $binary_remote_addr zone
设置用于保存各种key(比如当前连接数)的共享内存的参数。5m就是5兆字节,这个值应该被设置的足够大以存储(32K5)32byte状态或者(16K5)64byte状态。
limit_conn
为给定的key设置最大连接数。这里key是addr,我们设置的值是100,也就是说我们允许每一个IP地址最多同时打开有100个连接。
gzip_proxied
允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。
gzip_static
gzip_static on ;
告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件,从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了
open_file_cache
这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。
open_file_cache_valid
这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses
open_file_cache
指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。定义了open_file_cache中指令参数不活动时间期间里最小的文件数。
open_file_cache_errors
指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。
keepalive_requests
单个客户端在 keep-alive 连接上可以发送的请求数量,在测试环境中,需要配置个比较大的值。
最后,综上所述,配置文件如下:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 65535;
accept_mutex off;
multi_accept off;
}
http {
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
tcp_nodelay on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60;
send_timeout 10s;
types_hash_max_size 2048;
client_header_buffer_size 4k;
client_max_body_size 8m;
server{
location /{
proxy_buffering on;
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
}
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_http_version 1.0;
gzip_min_length 1024;
gzip_vary on;
gzip_comp_level 2;
gzip_buffers 32 4k;
gunzip_static on;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
}
}