Nginx调优


Nginx调优

并发数

基于nginx的多进程架构,通过合理配置worker_processes、worker_connections、worker_rlimit_nofile参数可调节nginx的最优并发。

worker_processes

在nginx配置文件全局块中,通过 worker_processes 参数配置worker 进程数,设置为 auto时,nginx则会自动设置与cpu核心数相同的数量worker 进程。

1
worker_processes auto;

worker_connection

1
2
3
events {
worker_connections 1024;
}

这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是 worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,如果是支持http1.1的浏览器每次访问要占两个连接( 并不是request和response响应占用两个连接 ),所以普通的静态访问最大并发数是:worker_connections * worker_processes / 2,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes / 4,因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,即2*2=4。

worker_rlimit_nofile

这个参数表示worker进程最多能打开的文件句柄数,基于liunx系统ulimit设置(Linux一切皆文件,所有请求过来最终目的访问文件,查看系统文件句柄数最大值(用户可以打开文件的最大数目):ulimit -n;一般root用户是65535,普通用户是1024)

1
2
3
# nginx配置文件全局块
# 配置nginx worker进程最大打开文件数
worker_rlimit_nofile 65535;

worker_rlimit_nofile 理论值应该是最多打开文件数(ulimit -n)与nginx worker进程进程数相除,但是nginx分配请求并不是那么均匀,所以与ulimit -n的值保持一致为优。

所以 worker_connections 值不能超过 worker_rlimit_nofile ,否则在高并发下可能会出现“too many open files”的异常。

nginx长连接

保持和客户端的长连接

一般情况下,nginx已经自动开启了对客户端(浏览器)连接的keep alive(http1.1)支持。

同时可设置以下两个配置:

1
2
3
4
http {
keepalive_timeout 120s 120s;
keepalive_requests 10000;
}
  • keepalive_timeout
    指令格式:keepalive_timeout timeout [header_timeout];

    timeout :设置keep-alive客户端连接在服务器端保持开启的超时值(默认75s);值为0即禁用keep-alive客户端连接;
    header_timeout:可选,在响应的header域中设置一个值“Keep-Alive: timeout=time”;通常可不设置;
    timeout默认75s,一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大。

  • keepalive_requests
    keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭,默认为100。

    该参数的工作机制:一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。

保持和server的长连接

nginx访问后端server(nginx称为upstream,上游服务器)默认用的是短连接的HTTP1.0协议,客户端请求到达时,nginx与后端建立连接,后端响应完毕后主动关闭该连接。

为了让nginx和后端server之间保持长连接,一般指明nginx请求后端服务的协议为http1.1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
upstream BACK_SERVER {
server 10.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server 10.0.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300; // 设置空闲连接的最大数量
}
server {
listen 8080;
server_name www.myapp.com;
location / {
proxy_pass http://BACK_SERVER ;
# 其它配置...
proxy_http_version 1.1;// 指明请求后端的协议
proxy_set_header Connection ""; // 清理来自客户端的Connection请求头
}
}
}

其中proxy_set_header Connection "";指令作用时清理来自客户端的Connection请求头,因为http1.1保持开启的长连接的关键是Connection请求头, 因为如果客户端和nginx之间是短连接(http1.0),我们把Connection请求头也带到后端,那么nginx与后端就不会开启长连接了,所以此处需要清除。

upstream块的keepalive

官方解释:设置到upstream服务器的空闲keepalive连接的最大数量, 当这个数量被突破时,最近使用最少的连接将被关闭,keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量。

1
2
3
4
5
upstream  BACK_SERVER {
server 10.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server 10.0.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300;
}

说白了就是nginx往后端服务器发的请求的空闲连接的最大数量,假设keepalive设置为30,此时来了100个请求,nginx新建了100个线程去请求后端,那么请求结束后,nginx会关闭100-30=70个线程,此时又再来了100个请求,nginx必须再新建70个线程去请求后端,之前30个线程被复用。所以合理配置keepalive是很有必要的。

一般把upstream块的keepalive配置和保持和server长连接的配置结合使用。

持续更新……