Javaを使用して多数の同時ダウンロード(サーバーあたり約500)を処理しています。
すべてのファイルはAmazonS3からダウンロードされており、ダウンロードサーバーはEC2m1.largeインスタンスです。
場合によっては、2つ以上のストリームが同時に壊れて、Java.net.SocketExceptionが発生することがあります。場合によっては、最大10個のストリームが同時に中断されることがあります。
AmazonS3サーバーとAkamaiサーバーの両方から同じ結果をダウンロードしています。これは、負荷が非常に高くなり始めた場合にのみ発生します(200以上の同時ダウンロード)。
私は通常のCPU、ネットワーク負荷、およびメモリの範囲内にあります。
問題はサーバーにあり、S3やAkamaiの問題ではないことを強く疑っています。これをデバッグして原因を突き止めるにはどうすればよいですか?
tcpdump
を使用してトラフィックをキャプチャし、接続が切断された後にそれを確認できます。たとえば、Wiresharkには「follow TCP stream」」オプションがあり、最後のパケットを見つけたら、壊れたパケットを簡単に分離できます。
まだかなりの量のデータを処理する必要があるかもしれませんが、負荷が非常に高い場合にのみ発生するとおっしゃっていますが、それを回避する方法はないと思います。
まず、ネットワークインターフェイス(ifconfig
を介して)によって報告されたエラーを調べて、接続が切断されたときにその数が大幅に増加するかどうかを確認できます。
あなたとS3の間のパスにファイアウォール/ NATはありますか?
同時にキャプチャできますか(tcpdump -w file -s 0
)サーバーとファイアウォールの間、およびファイアウォールとS3の間の2つのポイントでのトラフィック、次にダンプを比較しますか? tcpdumpを起動する前に、キャプチャホストでNTP)を使用してクロックが正確に同期されていることを確認してください。
次に、接続が切断された時点での両方のネットワークキャプチャを比較します。
同様のとらえどころのない問題があり、ネットワークトラフィックダンプを比較したところ、LinuxサーバーでSACKがアクティブになっていることが原因であることがわかりましたが、インターネットからのトラフィックを処理するCiscoASAファイアウォールによって不適切に解釈されていました。
Sysctlを使用してSACKを無効にする必要がありました(net.ipv4.tcp_sack
)。