Java (网络套接字)字节卡在发送队列中15分钟;为什么?

Java (网络套接字)字节卡在发送队列中15分钟;为什么?,java,networking,routing,firewall,Java,Networking,Routing,Firewall,我有一个运行在Windows(Citrix机器)上的Java程序,它向Linux上的Java应用服务器发送请求;这种调度机制都是定制的 Windows Java程序(我们称之为W)打开一个监听套接字,该套接字指向操作系统给定的端口,比如1234,以接收结果。然后,它使用“业务请求”调用服务器上的“分派”服务。此服务拆分请求并将其发送到其他服务器(我们称之为S1…Sn),并同步将作业数返回给客户端 在我的测试中,有13个作业被分派到多个服务器,在2秒内,所有服务器都已完成作业处理,并尝试将结果发送

我有一个运行在Windows(Citrix机器)上的Java程序,它向Linux上的Java应用服务器发送请求;这种调度机制都是定制的

Windows Java程序(我们称之为
W
)打开一个监听套接字,该套接字指向操作系统给定的端口,比如1234,以接收结果。然后,它使用“业务请求”调用服务器上的“分派”服务。此服务拆分请求并将其发送到其他服务器(我们称之为
S1…Sn
),并同步将作业数返回给客户端

在我的测试中,有13个作业被分派到多个服务器,在2秒内,所有服务器都已完成作业处理,并尝试将结果发送回
W
的套接字

我可以在日志中看到,
W
(这个数字因测试而异)收到了9个作业。所以,我试着寻找剩下的4份工作。如果在此Windows框上执行
netstat
,我会看到4个套接字打开:

TCP    W:4373       S5:48197  ESTABLISHED
TCP    W:4373       S5:48198  ESTABLISHED
TCP    W:4373       S6:57642  ESTABLISHED
TCP    W:4373       S7:48295  ESTABLISHED
如果我执行
W
的线程转储,我会看到4个线程试图从这些套接字读取,并且显然卡在
java.net.SocketInputStream.socketRead0(本机方法)

如果我在每个
S
框上执行
netstat
,我会看到一些字节仍在发送队列中。此字节数在15分钟内不会移动。(以下是不同计算机上的
netstat
s的聚合):

如果我对服务器进行线程转储,我会看到线程也被卡住了
java.net.SocketInputStream.socketRead0(本机方法)
。我希望能收到一封信,但也许他们在等回信?(此处不确定;是否会在Java中显示?是否应该由TCP协议直接处理?)

现在,非常奇怪的事情是:15分钟后(通常是15分钟),结果被接收,套接字被关闭,一切正常

以前总是这样。
S
服务器移动到不同的数据中心,因此
W
S
不再位于同一数据中心。而且,
S
位于防火墙后面。所有端口都应该在
S
W
之间授权(我被告知)。神秘的是15分钟的延迟。我以为它可以对DDOS提供一些保护

我不是网络专家,所以我请求帮助,但没有人可以帮助我。我花了30分钟和一个家伙用Wireshark(以前是Ethereal)捕获数据包,但出于“安全原因”,我无法查看结果。他必须分析这件事然后给我回电话。我要了防火墙日志;同样的故事


我不是这些盒子的root或管理员,现在我不知道该怎么办。。。我并不期待你们能给出解决方案,但一些关于如何进步的想法会很好

对。如果您使用的是BufferedOutputStream,则需要调用flush(),除非达到最大缓冲区大小。

如果它在本地网络中正常工作,则我认为这不会成为编程问题(请参阅
flush()
注释)

两台机器之间的网络连接正常吗?你能通过(比如)FTP毫无问题地传输类似数量的数据吗。您可以通过组合一个客户机/服务器脚本来发送适当大小的数据块来复制这个问题。i、 e.W和S之间的网络连接是否良好

另一个问题。现在中间有一个防火墙。这可能是以前没有的瓶颈吗?(但不确定这将如何解释持续的15米延迟)

最后一个问题。您的TCP配置参数设置为什么(在W和S上-我考虑的是操作系统级参数)。是否有任何迹象表明或导致1500万人死亡


不确定这是否有帮助。

除了尝试布赖恩所说的,你还可以检查以下内容

1) 在任意一台服务器上运行tcpdump,查看从作业启动到延迟后所有处理完成的消息流顺序。这将告诉您是哪一方造成延迟(W或S)。检查是否有任何重传、丢失的确认等

2) W和S之间是否存在某种碎片

3) 字节被卡住的服务器上的网络负载情况如何?重载是否会导致输出错误,导致套接字队列无法清空?(也可能存在NIC错误,在遇到某些错误情况后,NIC缓冲区未刷新,或无法恢复传输,并且此类情况正在被某种看门狗清除)

关于以上两个方面的更多信息肯定会有所帮助。

您确定卡在读取调用中的线程与发送数据的线程相同吗?是否有可能实际上涉及的线程在其他活动上被阻塞,而您的stackdump显示了其他碰巧正在执行套接字i/o的无辜线程?我已经有一段时间没有使用Java了,但我模糊地记得JVM使用套接字进行IPC

我会检查所有的接收端,看看其中是否有一个是预期的接收端,而是在15分钟内做其他事情


它在一个位置与另一个位置工作的事实通常表明是应用程序计时错误,而不是数据中心问题

没有足够的权限运行tcpdump,但这正是我试图与网络人员一起做的。不确定网络状况。在W和S所在的子网上,负载较低,但数据包通过的路由器可能存在瓶颈。是的,我确定。有问题的线程位于专用线程池中,名称不同。我不理解导致应用程序的时间安排背后的逻辑。但是我同意15分钟对于网络超时来说是相当多的
Proto Recv-Q Send-Q Local Address               Foreign Addr   State
tcp        0   6385 S1:48197                          W:4373   ESTABLISHED
tcp        0   6005 S1:48198                          W:4373   ESTABLISHED
tcp        0   6868 S6:57642                          W:4373   ESTABLISHED
tcp        0   6787 S7:48295                          W:4373   ESTABLISHED