一个connect time out问题的排查

1,134 阅读2分钟

问题

项目的部署架构情况如下:

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报文存在超时重传的情况

原因排查

各种猜想和论证,如下:

  1. 猜想一:跟net.ipv4.tcp_tw_recycle和net.ipv4.tcp_timestamps有关

不成立,因为服务器的net.ipv4.tcp_tw_recycle是关闭的,而且应用都是走内网

  1. 猜想二:跟SYN半连接队列有关

不成立,因为服务器的syncookies是开启的

  1. 猜想三:跟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更新

这个问题并没有实质找到原因,简单粗暴的方法是,把有问题的服务迁移到另外一台机器,就没有出现这个问题了

参考:

zhuanlan.zhihu.com/p/64690239

www.infoq.cn/article/wwb…