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的连接是长连接
    img.png

    nginx与keepalive相关的配置介绍

    场景1,配置TCP层keepalive探活机制的三个参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    case1:
    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分钟
    }
    }

    其中so_keepalive有如下选择配置,官方文档:so_keepalive
    1
    2
    3
    4
    5
    6
    so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]
    * on: 开启,探测参数更加系统默认值
    * off: 关闭
    * keepidle: 连接空闲等待时间
    * keepintvl: 发送探测报文间隔时间
    * keepcent: 探测报文重试次数
    每个参数主要是覆盖linux系统针对keepalive的默认配置,如果nginx未设置so_keepalive配置,则走系统默认的探活策略

场景2、nginx与客户端(一般为浏览器、APP等)保持的长连接进行限制管理;

1
2
3
4
http {
keepalive_timeout 120s 120s;
keepalive_requests 100;
}

客户端请求header头:

1
2
3
GET /uri  HTTP/1.1      #版本为1.1及以上,Connection:为空也开启长连接,但Connection:close时不开启
Host: www.baidu.com
Connection: keep-alive #Connection:keep-alive 时均开启长连接,HTTP是否为1.1以上无影响
  • keepalive_timeout: 第一个参数:客户端连接在服务器端空闲状态下保持的超时值(默认75s);值为0会禁用keep-alive,也就是说默认不启用长连接;第二个参数:响应的header域中设置“Keep-Alive: timeout=time”;告知浏览器对长连接的维持时间;
    官方文档:keepalive_timeout
  • keepalive_requests:默认100,某个长连接连续处理请求次数限制,超过次数则该长连接被关闭;如果需要释放某个连接占用的内存,必须关闭该链接,内存不大的情况下,不建议开大该配置;在QPS较高的场景,则有必要加大这个参数;
    官方文档:keepalive_requests

场景3、nginx与上游server保持长连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
upstream BACKEND {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
keepalive 300; //空闲连接数
keepalive_timeout 120s;//与上游空闲时间
keepalive_requests 100;//与上游请求处理最大次数
}
server{
listen 8080;
location /{
proxy_pass http://BACKEND;
}
}
}
  • 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
2
3
4
5
6
7
8
9
10
11
http {
keepalive_timeout 120s 120s;
keepalive_requests 100;
server {
location / {
proxy_http_version 1.1; //设置与上游通信的
proxy_set_header Connection "";
proxy_pass http://BACKEND;
}
}
}

nginx的开启长连接会带来什么问题?

nginx上下游针对请求处理的超时时间配置不合理,导致报connection reset by peer问题,即低频502

此类问题主要原因为,客户端在对上游长连接fd读写时,正好此fd被上游服务器关闭了,此时会报connection reset by peer,所以需要尽量避免上游服务器主动断开连接;

参考文章

评论