(ネットワークソケット)15分間、送信キューで立ち往生バイト。どうして?
-
22-08-2019 - |
質問
私は、Linux上のJavaアプリケーションサーバにリクエストをディスパッチのWindows(Citrixのマシン)上で動作するJavaプログラムを持っています。このディスパッチメカニズムは、すべてのカスタムです。
WindowsのJavaプログラムが(のはW
それを呼びましょう)OSによって与えられたポートに待機ソケットを開き、結果を受け取るために1234を言います。それは、「ビジネスの要求」をサーバ上に「派遣」サービスを呼び出します。このサービスは、要求を分割し、他のサーバーに送信します(のはS1 ... Sn
それらを呼びましょう)、および同期クライアントへのジョブの数を返します。
私のテストでは、サーバーの数にして2秒以内に発送13個のジョブが、そこにある、すべてのサーバーは、彼らの仕事の処理を終了し、バックW
のソケットに結果を送信しようとしています。
私は(この数は試験をテストごとに異なる)9つのジョブがW
によって受信されたログで見ることができます。だから、私は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
sの集合体である)
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を待っていますか? (ここではわからない;?それはそれは直接TCPプロトコルによって処理されるべきではないJavaで表示されるでしょう)
さて、非常に奇妙なことがある:15分後に(と、それは常に15分です)、結果が受信され、ソケットが閉じられ、すべてが通常どおり継続されています。
これは、常に前に働いていました。 S
サーバは、異なるデータセンターに移動していないので、W
とS
は、もはや同じデータセンターです。また、S
は、ファイアウォールの内側にあります。すべてのポートがS
とW
の間で承認される必要があります(私は聞いています)。謎は本当に15分の遅延です。私はそれがDDOSに対して何らかの保護することができることを考えた?
私は助けを求めたので、私はネットワークの専門家だが、誰も私を助けるために利用できません。私は、Wiresharkの(以前のEthereal)でパケットをキャプチャ男と30分を費やしたが、「セキュリティ上の理由から、」私は結果を見てすることはできません。彼は、これを分析し、私に戻って取得する必要があります。私は、ファイアウォールのログを求めました。同じ話ます。
私は今、私はあなたたちから解決策を期待していないよ...何をするか分からない、これらのボックスにrootまたは管理者ではないんだけど、進歩する方法についていくつかのアイデアは素晴らしいことです!
解決
、その後、私は、これはプログラミングの問題(再。flush()
コメント)であることを想定していない。
は、そうでない場合は、通常の2台のマシン間のネットワーク接続ですか?あなたは何の問題もなく(例えば)FTP経由でデータの同様の量を転送することができます。あなただけのデータの適切なサイズのチャンクを送信するために一緒にクライアント/サーバースクリプトをノックすることで、この問題を再現することができます。すなわち、WとSの間のネットワーク接続の良いのですか?
もう一つの問題。これで、ファイアウォールを挟ん持っています。これは以前にはなかった可能性がボトルネックだろうか? (それはしかし、一貫した15メートルの遅れを説明するだろうかどうかはわかりません)。
最後の質問。 ( - 私はOSレベルのパラメータを考えているWとSの両方に)されるように設定あなたのTCPの設定パラメータはどのようなものです。何を示唆または15メートルの数値につながることがあります。
それはすべてのヘルプだかどうかわからない。
他のヒント
右。あなたはなBufferedOutputStreamを使用している場合、あなたは最大バッファサイズに達しない限り、フラッシュを()を呼び出す必要があります。
別にブライアンが言ったことをしようとしてから、あなたもチェックすることができ、次の
1)サーバのいずれかに実行tcpdumpを、およびメッセージのシーケンスは、すべての処理が完了するとジョブは、遅延後に開始された時点から流れてご覧ください。それは遅延(WまたはS)を原因となっている側を教えてくれます。任意の再送信があるかどうかをチェックし、その上でACKを逃した、と。
2)WとSの間で起こって断片化のいくつかの種類がありますか?
3)バイトが立ち往生されているサーバ上のネットワーク負荷条件は何ですか?空にされていないソケットのキューで、その結果、出力誤差の原因となる高負荷ですか? (また、いくつかのエラー状態を打った後、NICのバッファがフラッシュされ、または送信を再開するために失敗し、そして、そのような条件は、ウォッチドッグのいくつかの並べ替えによってクリア取得されていないされ、NICのバグがあるかもしれません)。
上記の二つの詳細については間違いなく役立つだろう。
あなたはの確認の読み取り呼び出しで立ち往生のスレッドがデータを送信したのと同じスレッドがあるということ?それは実際に関与スレッドではなく、いくつかの他のアクティビティにブロックされ、そしてあなたのSTACKDUMPはただのI / Oソケットをやっていることが起こる他の無実のスレッドを示すことは可能ですか?私は、Javaで働いていたので、それはしばらくしているが、私は漠然とIPCのためのソケットを使用してJVMを覚えています。
私はそれらのいずれかが意図した受信機である、代わりに15分間の何かをやっているかどうかを確認するために、すべての受信側を調べるでしょう。
は、別の対一箇所に働くという事実は通常、アプリケーションのタイミング誤差ではなく、データセンターの問題を指します。