nginx keepalive
keepalive是在TCP中一个可以检测死连接的机制,可以保持tcp长连接不被断开,属于tcp层功能。http1.1协议默认开启keepa-live保持长连接,主要作用是提高对tcp连接的复用率,减少创建连接过程给系统带来的性能损耗。
keepalive与keep-alive区别?
keepalive是tcp层长连接探活机制;
keep-alive是应用层http协议使用,在其头部Connection字段中的一个值,只是代表客户端与服务之间需要保持长连接,可以理解为通过此字段来告诉nginx此连接需要维持长连接,处理完别直接关闭连接。
nginx的keepalive会做哪些事情?
当使用nginx作为代理服务器时,这两点必然要满足:
- client到nginx的连接是长连接
- nginx到server的连接是长连接
nginx与keepalive相关的配置介绍
场景1,配置TCP层keepalive探活机制的三个参数
其中so_keepalive有如下选择配置,官方文档:so_keepalive1
2
3
4
5
6
7
8
9
10
11
12
13
14case1:
http {
server {
listen 127.0.0.1:3306 so_keepalive=on;//开启keepalive探活,探测策略走系统默认
}
}
case2:
http {
server {
listen 127.0.0.1:3306 so_keepalive=7m:75s:9;//把空闲时长从系统默认的5分钟改为了7分钟
}
}每个参数主要是覆盖linux系统针对keepalive的默认配置,如果nginx未设置so_keepalive配置,则走系统默认的探活策略1
2
3
4
5
6so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]
* on: 开启,探测参数更加系统默认值
* off: 关闭
* keepidle: 连接空闲等待时间
* keepintvl: 发送探测报文间隔时间
* keepcent: 探测报文重试次数
场景2、nginx与客户端(一般为浏览器、APP等)保持的长连接进行限制管理;
1 | http { |
客户端请求header头:
1 | GET /uri HTTP/1.1 #版本为1.1及以上,Connection:为空也开启长连接,但Connection:close时不开启 |
- keepalive_timeout: 第一个参数:客户端连接在服务器端空闲状态下保持的超时值(默认75s);
值为0会禁用keep-alive
,也就是说默认不启用长连接;第二个参数:响应的header域中设置“Keep-Alive: timeout=time”;告知浏览器对长连接的维持时间;
官方文档:keepalive_timeout - keepalive_requests:默认100,某个长连接连续处理请求次数限制,超过次数则该长连接被关闭;如果需要释放某个连接占用的内存,必须关闭该链接,内存不大的情况下,不建议开大该配置;在QPS较高的场景,则有必要加大这个参数;
官方文档:keepalive_requests
场景3、nginx与上游server保持长连接
1 | http { |
- keepalive:限制nginx某个worker最多空闲连接数,此处不会限制worker与上游服务长连接的总数,官方文档:keepalive
- keepalive_timeout:nginx与上游长连接最大空闲时间,默认值为60s;官方文档: keepalive_timeout
- keepalive_requests:nginx与上游长连接最大交互请求的次数,默认值为100;官方文档: keepalive_requests
除此之外,nginx与上游通信,http协议默认是走的http1.0,对客户端header头不会直接转发,且会把头部中Connection字段置为默认的”close”,要与上游保持长连接还需要加如下配置:
1 | http { |
nginx的开启长连接会带来什么问题?
nginx上下游针对请求处理的超时时间配置不合理,导致报connection reset by peer
问题,即低频502
此类问题主要原因为,客户端在对上游长连接fd读写时,正好此fd被上游服务器关闭了,此时会报connection reset by peer,所以需要尽量避免上游服务器主动断开连接;