我正在使用 Java 处理大量并发下载(每个服务器约 500 个)。
所有文件均从 Amazon S3 下载,下载服务器是 EC2 m1.large 实例。
有时,会有 2 个或更多的流同时地中断,导致 java.net.SocketException。有时多达 10 个流会同时中断。
我从 Amazon S3 和 Akamai 服务器下载时得到的结果相同。只有当负载开始变得相当高时(200 个或更多并发下载)才会发生这种情况。
我完全处于正常的 CPU、网络负载和内存范围内。
我强烈怀疑问题出在我的服务器上,而不是 S3 和 Akamai 的服务器上。我该如何调试并找出原因?
答案1
您可以使用捕获流量,tcpdump
然后在连接中断后查看。例如,Wireshark 有一个选项“跟踪 TCP 流”,可以让您在找到最后一个数据包后轻松隔离中断的数据包。
可能仍然需要处理大量数据,但正如您所说,这种情况只有在负载很高时才会发生,所以我认为没有办法解决这个问题。
首先,您可以查看网络接口报告的错误(通过ifconfig
),并查看连接断开时该数字是否显著增加。
答案2
您和 S3 之间的路径上是否有防火墙/NAT?
您能否同时捕获(tcpdump -w file -s 0
)两点的流量 - 您的服务器和防火墙之间以及防火墙和 S3 之间的流量,然后比较转储?在启动 tcpdump 之前,请确保使用捕获主机上的 NTP 精确同步时钟。
然后在连接断开时比较两个网络捕获的情况。
我遇到了类似的难以捉摸的问题,通过比较网络流量转储,我发现这是由于 SACK 在我的 Linux 服务器上处于活动状态,但被处理来自互联网的流量的 Cisco ASA 防火墙错误地解释。
必须使用 sysctl ( net.ipv4.tcp_sack
) 禁用 SACK。