Nginx基本参数优化
1 . worker_processes 1; # 指定 Nginx 要开启的进程数,结尾的数字就是进程的个数,可以为 auto。
这个参数调整的是 Nginx 服务的 worker 进程数,Nginx 有 Master 进程和 worker 进程之分,Master 为管理进程、真正接待“客户端”的是 worker 进程。
进程个数的策略:worker 进程数可以设置为等于 CPU 的核数。高流量高并发场合也可以考虑将进程数提高至 CPU 核数 x 2。这个参数除了要和 CPU 核数匹配之外,也与硬盘存储的数据及系统的负载有关,设置为 CPU 核数是个好的起始配置,也是官方建议的。
如果想省麻烦也可以配置为worker_processes auto;,将由 Nginx 自行决定 worker 数量。当访问量快速增加时,Nginx 就会临时 fork 新进程来缩短系统的瞬时开销和降低服务的时间。
2 . worker_cpu_affinity是配置 Nginx 进程与 CPU 亲和力的参数。默认情况下,Nginx 的多个进程有可能运行在同一个 CPU 核上,导致 Nginx 进程使用硬件的资源不均,这就需要制定进程分配到指定的 CPU 核上处理,达到充分有效利用硬件的目的。
//4核设置
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000
//8核配置
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000
当然,如果想省麻烦也可以配置workercpuaffinity auto;,将由 Nginx 按需自动分配。
3 . Nginx 最大打开文件数,指定Nginx进程最大可以打开的文件数目,此处要配合文件资源打开数目设置。
// vi /usr/local/nginx1.10/conf/nginx.conf
worker_rlimit_nofile 65535
4 . Linux内核系统连接数,Linux默认打开连接数是1024,可以使用ulimit -n 查看 ulimit -a 查看所有限制 (配合上面)
vi /etc/security/limits.conf
//打开配置文件增加
* soft nofile 65535
* hard nofile 65535
* soft noproc 65535
* hard noproc 65535
5 . Nginx 事件处理高效模型,标准事件模型select,poll 高效事件模型,Nginx 的连接处理机制在不同的操作系统中会采用不同的 I/O 模型,在 linux 下,Nginx 使用 epoll 的 I/O 多路复用模型,在 Freebsd 中使用 kqueue 的 I/O 多路复用模型,在 Solaris 中使用 /dev/poll 方式的 I/O 多路复用模型,在 Windows 中使用 icop,等等。具体配置如下
events {
//高效事件模型
use epoll;
//单个进程允许的最大连接数
worker_connections 65535;
//告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on
multi_accept on;
}
events 指令是设定 Nginx 的工作模式及连接数上限。use指令用来指定 Nginx 的工作模式。Nginx 支持的工作模式有 select、 poll、 kqueue、 epoll 、 rtsig 和/ dev/poll。当然,也可以不指定事件处理模型,Nginx 会自动选择最佳的事件处理模型。
events {
multi_accept on;
}
6 . worker_connections 单个进程允许的客户端最大连接数,通过调整控制连接数的参数来调整 Nginx 单个进程允许的客户端最大连接数。
events {
//单个进程允许的最大连接数
worker_connections 65535;
}
worker_connections 也是个事件模块指令,用于定义 Nginx 每个进程的最大连接数,默认是 1024。最大连接数的计算公式如下:
maxclients = workerprocesses * worker_connections;
如果作为反向代理,因为浏览器默认会开启 2 个连接到 server,而且 Nginx 还会使用fds(file descriptor)从同一个连接池建立连接到 upstream 后端。则最大连接数的计算公式如下:
maxclients = workerprocesses * worker_connections / 4;
另外,进程的最大连接数受 Linux 系统进程的最大打开文件数限制,在执行操作系统命令 ulimit -HSn 65535或配置相应文件后, worker_connections 的设置才能生效。
7 . multi_accept 配置获取更多连接数,默认情况下,Nginx 进程只会在一个时刻接收一个新的连接,我们可以配置multi_accept 为 on,实现在一个时刻内可以接收多个新的连接,提高处理效率。该参数默认是 off,建议开启。
events {
//告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on
multi_accept on;
}
8 . 开启高效传输模式
http {
//引入媒体类型文件
include mime.types;
//默认类型
default_type application/octet-stream;
……
//开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。
sendfile on;
//必须在sendfile开启模式才有效,防止网路阻塞,积极的减少网络报文段的数量(将响应头和正文的开始部分一起发送,而不一个接一个的发送。)
tcp_nopush on;
……
}
9 . http模块连接超时时间设置,nginx.conf 下http模块关于超时部分设置,主要目的是保护服务器资源,CPU,内存,控制连接数,因为建立连接也是需要消耗资源的。后面内容会详细讲解超时设置。
//客户端会话超时时间,秒
keepalive_timeout 60;
//防止网络阻塞
tcp_nodelay on;
//客户端请求头部的缓冲区大小,一般1k
client_header_buffer_size 4k;
//这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存
open_file_cache max=65535 inactive=60s;
//多长时间检查一次缓存的有效信息
open_file_cache_valid 30s;
//open_file_cache指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除
open_file_cache_min_uses 1;
//设置请求头的超时时间
client_header_timeout 15;
//设置请求体的超时时间
client_body_timeout 15;
//告诉nginx关闭不响应的客户端连接
reset_timedout_connection on;
//响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接
send_timeout 15;
//并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的
server_tokens off;
//上传文件大小限制
client_max_body_size 10m;
10 . GZip 调优,位于http模块,使用gzip压缩功能,可能为我们节约带宽,加快传输速度。Nginx启用压缩功能需要你来ngx_http_gzip_module模块,apache使用的是mod_deflate。一般我们需要压缩的内容有:文本,js,html,css,对于图片,视频,flash什么的不压缩,同时也要注意,我们使用gzip的功能是需要消耗CPU的!
//开启压缩功能
gzip on;
//设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。
gzip_min_length 1k;
//压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。
gzip_buffers 4 32k;
//压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可。
gzip_http_version 1.1;
//压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。
gzip_comp_level 6;
//用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩)
gzip_types text/plain text/css text/javascript application/json application/javascript
application/x-javascriptapplication/xml;
//varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据。
gzip_vary on;
gzip_proxied any;
探活配置
Nginx主要有类超时设置:客户端超时设置、代理超时设置。
客户端超时设置
对于客户端超时主要设置有读取请求头超时时间、读取请求体超时时间、发送响应超时时间、长连接超时时间。通过客户端超时设置避免客户端恶意或者网络状况不佳造成连接长期占用,影响服务端的可处理的能力。
client_header_timeout time:设置读取客户端请求头超时时间,默认为60s,如果在此超时时间内客户端没有发送完请求头,则响应408(RequestTime-out)状态码给客户端。
client_body_timeout time:设置读取客户端内容体超时时间,默认为60s,此超时时间指的是两次成功读操作间隔时间,而不是发送整个请求体的超时时间,如果在此超时时间内客户端没有发送任何请求体,则响应408(RequestTime-out)状态码给客户端。
send_timeout time:设置发送响应到客户端的超时时间,默认为60s,此超时时间指的也是两次成功写操作间隔时间,而不是发送整个响应的超时时间。如果在此超时时间内客户端没有接收任何响应,则Nginx关闭此连接。
keepalive_timeout timeout [header_timeout]:设置HTTP长连接超时时间,其中,第一个参数timeout是告诉Nginx长连接超时时间是多少,默认为75s。第二个参数header_timeout是用于设置响应头“Keep-Alive: timeout=time”,即告知客户端长连接超时时间。两个参数可以不一样,“Keep-Alive:timeout=time”响应头可以在Mozilla和Konqueror系列浏览器起作用,而MSIE长连接默认大约为60s,而不会使用“Keep-Alive: timeout=time”。如Httpclient框架会使用“Keep-Alive: timeout=time”响应头的超时(如果不设置默认,则认为是永久)。如果timeout设置为0,则表示禁用长连接。
此参数要配合keepalive_disable 和keepalive_requests一起使用。keepalive_disable 表示禁用哪些浏览器的长连接,默认值为msie6,即禁用一些老版本的MSIE的长连接支持。keepalive_requests参数作用是一个客户端可以通过此长连接的请求次数,默认为100。首先,浏览器在请求时会通过如下请求头告知服务器是否支持长连接。Request Header Connection:keep-alive。http/1.0默认是关闭长连接的,需要添加HTTP请求头“Connection:Keep-Alive”才能启用。而http/1.1默认启用长连接,需要添加HTTP请求头“Connection: close”才关闭。如果Nginx设置keepalive_timeout 5s,则浏览器会收到如下响应头。Response Header Connection:keep-alive。
代理超时设置
upstream backend_server {
server 192.168.61.1:9080 max_fails=2 fail_timeout=10s weight=1;
server 192.168.61.1:9090 max_fails=2 fail_timeout=10s weight=1;
}
server {
……
location /test {
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
proxy_send_timeout 5s;
proxy_next_upstream error timeout;
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 0;
proxy_pass http://backend_server;
add_header upstream_addr $upstream_addr;
}
}
backend_server定义了两个上游服务器192.168.61.1:9080(返回hello)和192.168.61.1:9090(返回hello2)。如上指令主要有三组配置:网络连接/读/写超时设置、失败重试机制设置、upstream存活超时设置。
网络连接/读/写超时设置
proxy_connect_timeout time:与后端/上游服务器建立连接的超时时间,默认为60s,此时间不超过75s。
proxy_read_timeout time:设置从后端/上游服务器读取响应的超时时间,默认为60s,此超时时间指的是两次成功读操作间隔时间,而不是读取整个响应体的超时时间,如果在此超时时间内上游服务器没有发送任何响应,则Nginx关闭此连接。
proxy_send_timeout time:设置往后端/上游服务器发送请求的超时时间,默认为60s,此超时时间指的是两次成功写操作间隔时间,而不是发送整个请求的超时时间,如果在此超时时间内上游服务器没有接收任何响应,则Nginx关闭此连接。
对于内网高并发服务,请根据需要调整这几个参数,比如内网服务TP999为1s,可以将连接超时设置为100~500毫秒,而读超时可以为1.5~3秒左右。
失败重试机制设置。
proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_403 | http_404 | non_idempotent | off ...:配置什么情况下需要请求下一台上游服务器进行重试。默认为“errortimeout”。error表示与上游服务器建立连接、写请求或者读响应头出错。timeout表示与上游服务器建立连接、写请求或者读响应头超时。invalid_header表示上游服务器返回空的或错误的响应头。http_XXX表示上游服务器返回特定的状态码。non_idempotent表示RFC-2616定义的非幂等HTTP方法(POST、LOCK、PATCH),也可以在失败后重试下一台上游服务器(即默认幂等方法GET、HEAD、PUT、DELETE、OPTIONS、TRACE才可以重试)。off表示禁用重试。
重试不能无限制进行,因此,需要如下两个指令控制重试次数和重试超时时间。
proxy_next_upstream_tries number:设置重试次数,默认0表示不限制,注意此重试次数指的是所有请求次数(包括第一次和之后的重试次数之和)。
proxy_next_upstream_timeout time:设置重试最大超时时间,默认0表示不限制。
即在proxy_next_upstream_timeout时间内允许proxy_next_upstream_tries次重试。如果超过了其中一个设置,则Nginx也会结束重试并返回客户端响应(可能是错误码)。
如下配置表示当error/timeout时重试upstream中的下一台上游服务器,如果重试的总时间超出了6s或者重试了1次,则表示重试失败(因为之前已经请求一次了,所以还能重试一次),Nginx结束重试并返回客户端响应。
upstream存活超时设置
max_fails和fail_timeout:配置什么时候Nginx将上游服务器认定为不可用/不存活。当上游服务器在fail_timeout时间内失败了max_fails次,则认为该上游服务器不可用/不存活。并在接下来的fail_timeout时间内从upstream摘掉该节点(即请求不会转发到该上游服务器)。
什么情况下被认定为失败呢?其由 proxy_next_upstream定义,不过,不管 proxy_next_upstream如何配置,error, timeout and invalid_header 都将被认为是失败。
如server 192.168.61.1:9090max_fails=2 fail_timeout=10s;表示在10s内如果失败了2次,则在接下来的10s内认定该节点不可用/不存活。这种存活检测机制是只有当访问该上游服务器时,采取惰性检查。可以使用ngx_http_upstream_check_module配置主动检查。
max_fails设置为0表示不检查服务器是否可用(即认为一直可用),如果upstream中仅剩一台上游服务器时,则该服务器是不会被摘除的,将从不被认为不可用。
遇到的问题:
Docker部署Nginx采用-v挂载宿主机磁盘方式,配置文件和日志存放在宿主机上。具体配置文件参考《Docker 安装Nginx》.
Nginx配置文件不停机刷新配置可以通过nginx -s reload刷新。
[root@localhost ~]# docker exec -it a43351300491 /bin/bash
root@a43351300491:/# nginx -s reload
或
[root@localhost ~]# docker exec -it a43351300491 nginx -s reload
问题:宿主机的nginx.conf修改对应容器内部的nginx.conf没有同步。
原因:理论上,修改了宿主机上的文件之后,会自动同步到容器中。但是实际上,却不是,这是因为Linux系统内部不使用文件名,而是使用inode号码识别文件。对于系统来说文件名只是inode号码便于识别的不同的文件。
当docker restart或run的时候两边的inode是一致的。
当在宿主机使用vi编辑之后,宿主机的inode变化了,但是容器内部的inode还是没变,这才导致容器内部的文件没有变化。
解决办法:
1、docker restart 容器ID/Name,这样服务将不可用情况。
2、docker run -v挂载目录,不要挂载文件,这样也能解决问题,但是Nginx这么做会报错,nginx启动需要指定挂载的nginx.conf.具体原因没有深究了。
3、使用echo输出内容到文件,不会改变inode号,而使用vi或vim编辑文件后使用wq保存则会改变inode号。但是大量的文件内容,echo比较麻烦。
4、宿主机修改/etc/vimrc和/etc/virc,设置set backupcopy=yes 参考文档
这样VI nginx.conf 容器内和宿主机就同步了。然后再使用nginx -s reload不停机刷新。