我有一个在Windows上运行的Java程序(Citrix机器),它向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(Native Method)
中。
如果我继续执行每个S
框并执行netstat
,我会看到一些字节仍在发送队列中。此字节数不会移动15分钟。 (以下是不同机器上netstat
的聚合):
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
如果我对服务器执行线程转储,我会看到线程也被卡住了
java.net.SocketInputStream.socketRead0(Native Method)
。我希望写一个,但也许他们在等待一个ACK? (这里不确定;它会用Java显示吗?不应该直接用TCP协议处理吗?)
现在,非常奇怪的是:15分钟后(总是15分钟),结果收到,套接字关闭,一切都正常。
以前一直都这样。 S
服务器已移至其他数据中心,因此W
和S
不再位于同一数据中心。此外,S
位于防火墙后面。所有端口都应在S
和W
之间授权(我被告知)。神秘的确是15分钟的延迟。我认为这可能是对DDOS的一些保护吗?
我不是网络专家,所以我求助,但没有人可以帮助我。我花了30分钟与一个人用Wireshark(以前的Ethereal)捕获数据包,但出于“安全原因”,我无法查看结果。他必须分析这个并回复我。我问了防火墙日志;同样的故事。
我不是这些盒子的根或管理员,现在我不知道该做什么......我不期待你们的解决方案,但是关于如何进步的一些想法会很棒!
答案 0 :(得分:3)
如果它在您的本地网络中运行正常,那么我不认为这是一个编程问题(重新flush()
评论)。
两台机器之间的网络连接是否正常?您可以通过(比如)FTP传输类似数量的数据,没有任何问题。您是否可以通过将客户端/服务器脚本组合在一起来发送适当大小的数据块来复制此问题。即W和S之间的网络连接是否良好?
另一个问题。你现在有一个防火墙。这可能是以前没有的瓶颈吗? (不知道如何解释一致的15米延迟)。
最后的问题。您的TCP配置参数设置为什么(在W和S上 - 我正在考虑操作系统级参数)。那里有什么可以暗示或导致15米的数字。
不确定是否有任何帮助。
答案 1 :(得分:1)
右。如果您正在使用BufferedOutputStream,则需要调用flush(),除非您达到最大缓冲区大小。
答案 2 :(得分:1)
除了尝试Brian说,您还可以查看以下内容
1)在任何一台服务器上运行tcpdump,并查看从启动作业到延迟之后,当所有处理完成时的消息流序列。这将告诉你哪一方导致延迟(W或S)。检查是否有任何重传,错过的确认等。
2)W和S之间是否存在某种碎片?
3)字节卡住的服务器上的网络负载条件是什么?重负载导致输出错误,导致套接字队列没有被清空? (也可能存在NIC错误,其中在遇到某些错误情况后,NIC缓冲区没有刷新,或者无法恢复传输,并且某种监视器会清除这种情况)
有关上述两项的更多信息肯定会有所帮助。
答案 3 :(得分:0)
您是否确定在读取调用中遇到的线程与发送数据的线程相同?是否有可能实际涉及的线程被阻塞在其他一些活动上,而你的stackdump显示其他无辜的线程恰好正在执行socket i / o?自从我使用Java以来已经有一段时间了,但我依稀记得使用套接字的JVM。
我会检查所有接收方,看看其中一个是否是预期的接收器,而是做了15分钟的其他事情。
它在一个位置与另一个位置工作的事实通常指向应用程序计时错误,而不是数据中心问题。