Nginx 支持 keep-alive 长连接
概念
Persistent HTTP connections have a number of advantages
HTTP
协议采用请求-应答模式,当使用普通模式,即非 KeepAlive
模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP
协议为无连接的协议);当使用 Keep-Alive
模式(又称持久连接/连接重用)时,Keep-Alive
功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive
功能避免了建立或者重新建立连接。
支持 keep alive
当使用 nginx
作为反向代理时,为了支持长连接,需要做到两点
从
client
到nginx
的连接是长连接从
nginx
到server
的连接是长连接
保持和 client
的长连接
client
发送的HTTP
请求要求keep alive
nginx
设置上支持keep alive
HTTP
配置
keepalive_timeout
默认
75s
,一般情况下也够用,对于一些请求比较大的内部服务器通讯的场景,适当加大为120s
或者300s
。第二个参数通常可以不用设置
第一个参数设置 keep-alive
客户端连接在服务器端保持开启的超时值。值为 0
会禁用 keep-alive
客户端连接。可选的第二个参数在响应的 header
域中设置一个值 Keep-Alive: timeout=time
。这两个参数可以不一样
keepalive_requests
默认
100
,对于QPS
较高的场景,非常有必要加大这个参数,以避免出现大量连接被生成再抛弃的情况,减少TIME_WAIT
。这个参数的真实含义是指一个keep alive
建立之后,nginx
就会为这个连接设置一个计数器,记录这个keep alive
的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx
会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接
用于设置一个 keep-alive
连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭
保持和 server
的长连接
http {
keepalive_timeout 100s;
keepalive_requests 1000;
upstream dev.proxy.com {
server 192.168.10.11:8081 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.10.10:8081 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300;
}
server {
listen 80 default_server;
listen [::]:80 ipv6only=on;
server_name dev.proxy.com;
charset utf-8;
location / {
index index.php index.html index.htm;
proxy_pass http://dev.proxy.com/;
proxy_set_header Host $Host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
add_header Cache-Control no-store;
add_header Pragma no-cache;
proxy_http_version 1.1;
proxy_set_header Connection "";
client_max_body_size 3072k;
client_body_buffer_size 128k;
}
}
}
合理的设置 keep-alive
值可以非常有效的缓冲请求和应答不均匀,缓解连接数量的反复震荡
连接数量震荡的两个表现
连接不够用,造成新建连接
连接空闲,造成关闭连接
统计在一台前端机上高峰时间 TCP 连接的情况
$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}'
导致 nginx
端出现大量 TIME_WAIT
的两种情况
keepalive_requests
设置比较小,高并发下超过此值后nginx
会强制关闭和客户端保持的keepalive
长连接(主动关闭连接后导致nginx
出现TIME_WAIT
)keepalive
设置的比较小(空闲数太小),导致高并发下nginx
会频繁出现连接数震荡(超过该值会关闭连接),不停的关闭开启和后端server
保持的keep-alive
长连接
导致后端 server
端出现大量 TIME_WAIT
的情况
nginx
没有打开和后端的长连接,即:没有设置proxy_http_version 1.1;
和proxy_set_header Connection "";
从而导致后端server
每次关闭连接,高并发下就会出现server
端出现大量TIME_WAIT