序言
在系统间交互频繁的场景中,连接数是一个重要的指标。通常,我们会为连接数设置一个告警阈值,比如几万。
当连接数超过这个阈值时,就会触发告警。连接数过多会消耗cpu、内存、文件句柄等资源。虽然可以通过提高阈值(如10万或30万)来暂时缓解告警问题,但只要cpu和内存资源未告警,情况还不算紧急。本文将详细介绍如何处理nginx服务器连接数告警问题。
服务端连接数异常告警排查
1. 查看连接状态
当nginx充当转发服务器时,连接数告警是很常见的,尤其是在qps(每秒查询数)很高的情况下。收到告警后,我们通常需要登录服务器,使用netstat或ss命令来查看连接状态。
注意:在使用ss命令时,如果命令格式和netstat类似,默认情况下ss不会显示time-wait状态的连接,因为ss认为这种状态不重要。
执行以下命令查看连接状态:
netstat -an | grep established # 或者 ss -ant | grep established
执行命令后,我们可以发现哪种状态的连接占用最多。在正常情况下,time-wait状态的连接可能占用很多。接下来,我们可以查看是哪些ip占用了大量连接。
在当前场景下,如果发现与后端服务连接的time-wait状态较多,即显示的都是nginx的upstream服务器,那么可以大致判断为nginx与upstream的连接是短连接,未开启长连接配置。
2. 查看nginx的配置
在默认情况下,如果在upstream的配置中没有特别设置,nginx与upstream的连接是短连接的。
特别需要注意的是keepalive参数,它限制的是空闲连接的数量(不会限制upstream的最大连接数)。以下是相关参数的配置:
syntax: keepalive_timeout timeout; default: keepalive_timeout 60s; context: upstream syntax: keepalive_requests number; default: keepalive_requests 1000; context: upstream
在一般情况下,这两个参数保持默认值即可。如果并发量很大,可以将keepalive设置为300,并将timeout和requests设置得大一点,以减少连接被释放的次数。
如果keepalive_timeout设置得很小,会导致连接不停地被释放和创建,最直接的影响是增大请求的响应时间(rt),消耗nginx的资源,并有更高的连接和关闭开销,同时也会影响后端服务器的性能。
在upstream的长连接需要关闭时,会按照四次挥手协议进行关闭,并且会等连接处理完成后再关闭,不会像某些框架那样到了时间直接关闭,不管请求是否结束。
3. 客户端的长连接
对于nginx来说,默认情况下就开启了客户端的长连接功能,所以一般只需要配置超时时间即可。
syntax: keepalive_timeout timeout [header_timeout]; default: keepalive_timeout 75s; context: http, server, location
需要注意的是,如果客户端的连接都是短连接,而没有长连接,那么需要检查客户端的请求头,查看connection头部是否为close,强制要求使用短连接。
另外,还需要查看客户端使用的协议是否是http/1.0(默认都是短连接)。如果未出现上述情况,那么需要检查nginx的配置中,是否将connection头部设置为空字符串,否则不但客户端是短连接,还会影响nginx和upstream之间也是短连接。
如果客户端发送的connection头部是close,但是nginx设置了connection头部为空字符串,那么nginx和后端依旧是长连接。
4. 优化操作系统的内核参数
如果发现客户端的连接有很多time-wait状态,可以通过优化操作系统的内核参数来解决。编辑/etc/sysctl.conf文件,添加或修改以下参数:
net.ipv4.tcp_keepalive_time = 1200 # 使用tcp探测尽快处理空闲的连接 net.ipv4.tcp_fin_timeout = 30 # 设置fin wait2等待时间,减少等待关闭连接的时间,尽快释放系统资源 net.ipv4.tcp_max_tw_buckets = 200000 # 控制timewait数量 net.ipv4.tcp_tw_recycle = 0 # 禁用timewait的快速回收,已废弃,防止潜在网络问题 net.ipv4.tcp_tw_reuse = 1 # 启用timewait状态的连接便于新的连接 net.ipv4.tcp_timestamps = 1 # 启用tcp时间戳选项,提高网络传输效率,提高tcp连接安全性 net.ipv4.netdev_max_backlog = 262148 # 允许入队列的数据包的最大数量
保存文件后,执行sysctl -p命令使配置生效。
运行结果示例
假设我们在服务器上执行了以下命令来查看连接状态:
ss -ant | grep established
可能得到如下输出:
estab 0 0 192.168.1.100:80 192.168.1.101:54321 estab 0 0 192.168.1.100:80 192.168.1.102:54322 ...
这表示有多个建立的连接。通过类似的方法,我们可以进一步分析具体哪些ip或端口占用了大量连接。
总结
nginx的复杂之处在于它既是客户端又是服务端。在充当客户端时,需要设置连接超时参数;在充当服务端时,也需要设置连接超时参数。并且这些参数的名字还差不多,只是写的位置不一样,有的是在http段中,有的是在upstream段中。通过仔细排查和优化配置,我们可以有效解决nginx服务器连接数告警问题。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论