TCP Socket挂起 - 两侧卡在sendto()

时间:2011-09-15 10:29:58

标签: linux sockets hang sendto

我们有一个似乎挂起的linux应用程序(我们没有源代码)。两个进程之间的套接字报告为ESTABLISHED,并且内核套接字缓冲区中有一些数据(尽管通过wmem / rmem在配置的16M附近)。套接字的两端似乎都卡在了sendto()上。

以下是使用netstat / lsof和strace的一些调查:

主持人A(10.152.20.28)

[root@hosta ~]# lsof -n -u df01 | grep 12959 | grep 12u
q         12959 df01   12u  IPv4            4398449                TCP 10.152.20.28:38521->10.152.20.29:gsigatekeeper (ESTABLISHED)

[root@hosta ~]# netstat -anp | grep 38521
tcp   268754  90712 10.152.20.28:38521          10.152.20.29:2119           ESTABLISHED 12959/q

[root@hosta ~]# strace -p 12959
Process 12959 attached - interrupt to quit
sendto(12, "sometext\0somecode\0More\0exJKsss"..., 542, 0, NULL, 0 <unfinished ...>
Process 12959 detached
[root@hosta~]#

主持人B(10.152.20.29)

[root@hostb ~]# netstat -anp | grep 38521
tcp    72858 110472 10.152.20.29:2119           10.152.20.28:38521          ESTABLISHED 25512/q

[root@hostb ~]# lsof -n -u df01 | grep 38521
q         25512 df01   14u  IPv4            6456715                 TCP 10.152.20.29:gsigatekeeper->10.152.20.28:38521 (ESTABLISHED)

[root@hostb ~]# strace -p 25512
Process 25512 attached - interrupt to quit
sendto(14, "\0\10\0\0\0Owner\0sym\0Type\0Ctpy\0Time\0Lo"..., 207, 0, NULL, 0 <unfinished ...>
Process 25512 detached
[root@hostb~]#

我们已将NIC驱动程序升级到最新版本。系统正在运行RHEL 5.6 x64(2.6.18-238.el5),我已经检查了RHEL 5.7和5.8的eratta,但我看不到bnx2驱动程序或内核的错误。

有没有人对如何进一步调试这个有什么想法?

1 个答案:

答案 0 :(得分:3)

双方是否实际上正在阅读?如果不是,则可能是双方的接收缓冲区已满,导致不发送数据(由于接收窗口被填满),导致两个发送缓冲区都被填满,这将导致sendto阻塞。 (如果应用程序正在设置SO_RCVBUFSO_SNDBUF套接字选项,尽管您设置了wmem / rmem,可能会发生这种情况。)

要对此进行调试,我会同步两台机器的时钟,然后使用strace-e trace=network选项运行-tt下的两个应用程序,以便您可以比较日志并查看是否申请不是在阅读。

您还可以使用网络分析器(例如Wireshark)来确定TCP接收窗口是否卡在0上。

如果是这种情况,你可以通过创建一个小的缓存代理来解决这个问题,它会从双方收回/发送,缓冲当时无法发送的内容。