最近在进行服务器的优化,正好在看nginx相关的知识,因此把一些知识整理一下。参考资料为《Nginx高性能web服务器详解》,建议你们都去读读这本书。
个人机器为四核CPU,16G内存。javascript
把以下的参数追加到Linux系统的/etc/sysctl.conf
文件中,而后使用以下命令使修改生效:/sbin/sysctl -p
css
net.core.netdev_max_backlog = 262144 net.core.somaxconn = 262144 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1
参数net.core.netdev_max_backlog,表示当每一个网络接口接受数据包的速率比内核处理这些包的速率快时,容许发送队列的数据包的最大数目,咱们调整为262144.java
该参数用于调节系统同时发起的TCP链接数,通常默认值为128,在客户端高并发的请求的状况下,该默认值较小,可能致使链接超时或者重传问题,咱们能够根据实际状况结合并发数来调节此值。node
该参数用于设定系统中最多容许存在多少TCP套接字不被关联到任何一个用户文件句柄上,若是超过这个数字,没有与用户文件句柄关联到TCP套接字将当即被复位,同时发出警告信息,这个限制只是为了简单防治Dos攻击,通常系统内存充足的状况下,能够增大这个参数。linux
该参数用于记录还没有收到客户端确认信息的链接请求的最大值,对于拥有128内存的系统而言,此参数的默认值为1024,对小内存的系统则是128,通常在系统内存比较充足的状况下,能够增大这个参数的赋值。nginx
该参数用于设置时间戳,这个能够避免序列号的卷绕,在一个1Gb/s的链路上,遇到之前用过的序列号几率很大,当此值赋值为0时,警用对于TCP时间戳的支持,默认状况下,TCP协议会让内核接受这种异常的数据包,针对Nginx服务器来讲,建议将其关闭。web
该参数用于设置内核放弃TCP链接以前向客户端发送SYN+ACK包的数量,为了创建对端的链接服务,服务器和客户端须要进行三次握手,第二次握手期间,内核须要发送SYN并附带一个回应前一个SYN的ACK,这个参数主要影响这个过程,通常赋予值为1,即内核放弃链接以前发送一次SYN+ACK包。编程
该参数的做用与上一个参数相似,设置内核放弃创建链接以前发送SYN包的数量,赋值为1。json
nginx的配置文件以下:后端
user www-data; pid /run/nginx.pid; 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 { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60 50; send_timeout 10s; types_hash_max_size 2048; client_header_buffer_size 4k; client_max_body_size 8m; include /etc/nginx/mime.types; default_type application/octet-stream; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_disable "msie6"; 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; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
worker_processes用来设置Nginx服务的进程数。推荐是CPU内核数或者内核数的倍数,推荐使用CPU内核数,由于个人CPU为4核的,因此设置为4。
默认状况下,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上,致使Nginx进程使用硬件的资源不均,所以绑定Nginx进程到不一样的CPU上是为了充分利用硬件的多CPU多核资源的目的。
worker_cpu_affinity用来为每一个进程分配CPU的工做内核,参数有多个二进制值表示,每一组表明一个进程,每组中的每一位表明该进程使用CPU的状况,1表明使用,0表明不使用。因此咱们使用worker_cpu_affinity 0001 0010 0100 1000;
来让进程分别绑定不一样的核上。
设置一个进程理论容许的最大链接数,理论上越大越好,但不能够超过worker_rlimit_nofile的值。还有个问题,linux系统中有个指令open file resource limit,它设置了进程能够打开的文件句柄数量,能够用下面的指令查看你的linux系统中open file resource limit指令的值,cat /proc/sys/fs/file-max
能够将该指令设置为23900251echo "2390251" > /proc/sys/fs/file-max; sysctl -p
设置毎个进程的最大文件打开数。若是不设的话上限就是系统的ulimit –n的数字,通常为65535。
设置事件驱动模型使用epoll。事件驱动模型有select、poll、poll等。
这个牵扯到《UNIX网络编程》第一卷中提到的“惊群”问题(Thundering herd problem),大体意思是当某一时刻只有一个网络链接到来时,多个睡眠进程会被同时叫醒,但只有一个进程可得到链接,若是每次唤醒的进程数目太多,会影响一部分系统性能。在Nginx服务器的多进程下,就可能出现这个问题,为了解决这个问题,Nginx配置了包含这样一条指令accept_mutex,当其设置为开启的时候,将会对多个Nginx进程接受链接进行序列化,防止多个进程对链接的争抢。当服务器链接数很少时,开启这个参数会让负载有必定程度的下降。可是当服务器的吞吐量很大时,为了效率,请关闭这个参数;而且关闭这个参数的时候也可让请求在多个worker间的分配更均衡。因此咱们设置accept_mutex off;
使用开启或关闭是否使用sendfile()传输文件,普通应用应该设为on,下载等IO重负荷的应用应该设为off,由于大文件不适合放到buffer中。
传统文件传输中(read/write方式)在实现上3实际上是比较复杂的,须要通过屡次上下文切换,当须要对一个文件传输时,传统方式是:
从上面能够看出来,传统readwrite进行网络文件传输的方式,在过程当中经历了四次copy操做。
硬盘->内核buffer->用户buffer->socket相关缓冲区->协议引擎
而sendfile系统调用则提供了一种减小屡次copy,提升文件传输性能的方法。流程以下:
sendfile为on时这里也应该设为on,数据包会累积一下再一块儿传输,能够提升一些传输效率。
小的数据包不等待直接传输。默认为on。
看上去是和tcp_nopush相反的功能,可是两边都为on时nginx也能够平衡这两个功能的使用。
HTTP链接的持续时间。设的太长会使无用的线程变的太多。这个根据本身服务器访问数量、处理速度以及网络情况方面考虑。
设置Nginx服务器响应客户端的超时时间,这个超时时间只针对两个客户端和服务器创建链接后,某次活动之间的时间,若是这个时间后,客户端没有任何活动,Nginx服务器将关闭链接,将其设置为10s,Nginx与客户端创建链接后,某次会话中服务器等待客户端响应超过10s,就会自动关闭。
types_hash_max_size影响散列表的冲突率。types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会下降,检索速度就更快。types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。
该指令用于设置Nginx服务器容许的客户端请求头部的缓冲区大小,默认为1KB,此指令的赋值能够根据系统分页大小来设置,分页大小能够用如下命令获取getconf PAGESIZE
。
客户端上传的body的最大值。超过最大值就会发生413(Request Entity Too Large)错误。默认为1m,最好根据本身的状况改大一点。
启用gzip,对响应数据进行在线实时压缩,减小数据传输量。
Nginx服务器在响应这些种类的客户端请求时,不使用Gzip功能缓存应用数据,gzip_disable "msie6"对IE6浏览器的数据不进行GZIP压缩。
Gzip压缩功能对大数据的压缩效果明显,可是若是压缩很小的数据,可能出现越压缩数据量越大的状况,所以应该根据相应页面的大小,选择性开启或者关闭Gzip功能。建议将值设置为1KB。
设置压缩程度,包括级别1到级别9,级别1表示压缩程度最低,压缩效率最高;级别9表示压缩程度最高,压缩效率最低,最费时间。
用于设置在使用Gzip功能时是否发送带有“Vary:Accept-Encoding”头域的响应头部,该头域的主要功能是告诉接收方发送的数据通过了压缩处理,开启后端效果是在响应头部Accept-Encoding: gzip,对于自己不支持Gzip的压缩的客户端浏览器是有用的。
该指令用于设置Gzip压缩文件使用存储空间的大小,
语法gzip_buffers number size;
number,指定Nginx服务器须要向系统申请存储空间的个数,size,指定每一个缓存空间的大小。根据配置项,Nginx服务器在对响应输出数据进行Gzip压缩时需向系统申请numbersize大小的空间用于存储压缩数据。默认状况下,numbersize的值为128,其中size的值为系统内存页一页的大小,用getconf PAGESIZE
来获取
开启时,若是客户端浏览器不支持Gzip处理,Nginx服务器将返回解压后的数据,若是客户端浏览器支持Gzip处理,Nginx服务器忽略该指令设置。仍然返回压缩数据。
Nginx服务器能够根据MIME类型选择性开启Gzip压缩功能。该指令涌来设置MIME类型。