问题
项目的部署架构情况如下:
client有三个集群应用,通过Nginx做负载均衡。
生产出现了一个connect time out(连接超时时间设置了60s)问题,情况如下:
应用报错:
HTTP异常: I/O error on POST request for "...": connect timed out; nested exception is java.net.SocketTimeoutException: connect timed out
抓包情况:
相同的请求地址,出现问题的应用只有client-01,其余两台没有出现这个问题。经过一下方式排查:
-
查server-01和server-02的日志,发现请求并未到达server
-
在client-01和nginx所在服务器上抓包,发现存在SYN报文存在超时重传的情况
原因排查
各种猜想和论证,如下:
- 猜想一:跟net.ipv4.tcp_tw_recycle和net.ipv4.tcp_timestamps有关
不成立,因为服务器的net.ipv4.tcp_tw_recycle是关闭的,而且应用都是走内网
- 猜想二:跟SYN半连接队列有关
不成立,因为服务器的syncookies是开启的
- 猜想三:跟accept连接队列有关
不确定,因为如果是这个原因,那么client-02和client-03也有可能会出现connect time out的问题,但实质情况只有client-01出现
结论
没有结论,目前没有思路。走过路过的,欢迎留言解答...
2021-03-08更新
尝试1:修改server-01和server-02的net.core.somaxconn,默认128,调整为200
结果:无效,依然产生超时问题
2021-03-11更新
尝试1的想法其实是有问题的,有一个前提是,上面抓包的数据,是client01请求nginx的包,也就是destination是nginx服务器,所以丢失SYN报文该是niginx服务器,而不是server01和server02。如果是server01和server02丢弃SYN报文的话,client01转到的该是read time out,因为client01和nginx服务器是成功地建立连接了,只是nginx和server01和server02建立连接超时,client01不可能抓到这部分的包
2021-06-23更新
这个问题并没有实质找到原因,简单粗暴的方法是,把有问题的服务迁移到另外一台机器,就没有出现这个问题了
参考: