4

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

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

在我的测试中,有 13 个作业被分派到多个服务器,并且在 2 秒内,所有服务器都完成了它们的作业并尝试将结果发送回W's 套接字。

我可以在日志中看到收到了 9 个作业W(这个数字因测试而异)。所以,我试着寻找剩下的 4 个工作。如果我netstat在这个 Windows 盒子上做一个,我看到 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执行java.net.SocketInputStream.socketRead0(Native Method).

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

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)捕获数据包,但出于“安全原因”,我无法查看结果。他必须对此进行分析并回复我。我询问了防火墙日志;相同的故事。

我不是这些盒子的 root 或管理员,现在我不知道该怎么办......我不期待你们提供解决方案,但是关于如何进步的一些想法会很棒!

4

4 回答 4

3

如果它在您的本地网络中运行良好,那么我不认为这是一个编程问题(重新flush()评论)。

否则两台机器之间的网络连接是否正常?您可以通过(例如)FTP 毫无问题地传输类似数量的数据吗?您是否可以通过组合客户端/服务器脚本来复制此问题,以发送适当大小的数据块。即 W 和 S 之间的网络连接是否良好?

另一个问题。你现在有一个防火墙。这可能是以前不存在的瓶颈吗?(虽然不确定这将如何解释一致的 15m 延迟)。

最后一个问题。您设置的 TCP 配置参数是什么(在 W 和 S 上 - 我正在考虑操作系统级别的参数)。那里有什么可以建议或导致 15m 的数字。

不确定这是否有帮助。

于 2009-04-02T17:35:52.043 回答
1

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

于 2009-04-02T15:25:31.763 回答
1

除了尝试Brian说的,您还可以检查以下内容

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

2) W 和 S 之间是否发生了某种碎片化?

3) 字节卡住的服务器上的网络负载情况如何?负载过重会导致输出错误,导致socket队列没有被清空吗?(也可能存在 NIC 错误,其中在遇到某些错误条件后,NIC 缓冲区未刷新,或者无法恢复传输,并且这种情况正在被某种看门狗清除)

有关上述两个的更多信息肯定会有所帮助。

于 2009-04-03T04:27:33.910 回答
0

确定卡在读取调用中的线程与发送数据的线程相同吗?是否有可能实际涉及的线程被其他活动阻塞了,而您的堆栈转储显示了其他恰好正在执行套接字 i/o 的无辜线程?自从我使用 Java 以来已经有一段时间了,但我隐约记得 JVM 使用套接字进行 IPC。

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

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

于 2009-04-03T22:20:49.557 回答