问题出现得很突然,日志倒是留得挺全。长连接业务每隔几分钟就断一次,服务端日志显示连接被对端重置,两端都说自己没有主动断。
原因不止一个,得分开看。中间防火墙或者负载均衡的空闲超时到了。另一种情况是会话表被清理,后续报文被重置。
还有一种情况,链路上有设备做了连接数限制。
动手时先抓包看重置报文的来源
tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0'
然后确认空闲多久会断
ss -tino dst 对端IP
再往下开启长连接保活
sysctl -w net.ipv4.tcp_keepalive_time=300
剩下的就是在应用层加心跳
grep -n keepalive /etc/nginx/nginx.conf
这次没动代码,只在配置和运行环境上找原因。
隔了一天再看,现象没变,说明不是偶发。
别只看报错消失,验证要多做一步。长连接稳定保持一小时以上,抓包里不再出现周期性重置。
提醒一点。保活间隔要小于中间设备的空闲超时,否则心跳还没来得及发,会话就已经被清掉了。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。