我们的一个数据库出现了连接上去之后info请求不返回的问题,为了找到问题原因,我做了一个tcpdump,结果发现,他有大量重传tcp的第二个,第三个握手包,并且在重传几次之后reset:
嗯,第一个syn包重传我遇到过了,见我之前的文章,但是第二个和第三个同时重传的,我还真没遇到过。而且在我的环境下,这个问题很神奇,因为:
- 第一个包能到达,因为返回了第二个syn包。说明网络是好的。
- 第二个包也回来了,说明linux认为连接能被建立。
- 已经建立的连接,通讯完全正常。
- 当时cpu负载并不高,至少操作系统没有很忙。
- 连接数不多,大概就两百个左右。
- 检查了防火墙, 没有任何过滤条件
我查了一下netstat,发现该端口有大量的close_wait的连接,于是怀疑是不是服务器的哪里阻塞住了,导致了这个问题。并且所有close wait的连接,recv queue都是有15byte数据等待读取的,让我更加怀疑这个是服务器没有正确处理socket读取请求导致的问题。
直觉让我认为,有可能是服务器的应用在忙着做什么东西,导致一直没有accept连接。但是已经accept的,可能在其他线程正常工作。
Listen Queue Length
如果写过linux socket的人可能知道,一般创建一个端口并监听,连接,需要以下动作:
-
<