Linux上のJavaアプリケーションサーバーにリクエストをディスパッチするJavaプログラムをWindows(Citrixマシン)で実行しています。このディスパッチングメカニズムはすべてカスタムです。
Windows Javaプログラム(これを呼びましょうW
)は、結果を受信するために、OSによって指定されたポート(たとえば1234)へのリッスンソケットを開きます。次に、「ビジネスリクエスト」を使用してサーバー上で「ディスパッチ」サービスを呼び出します。このサービスは、リクエストを分割して他のサーバーに送信し(それらを呼び出しましょうS1 ... Sn
)、ジョブの数を同期的にクライアントに返します。
W
私のテストでは、13個のジョブがあり、多数のサーバーにディスパッチされ、2秒以内にすべてのサーバーがジョブの処理を終了し、結果をのソケットに返送しようとします。
ログを見ると、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
、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を待っていますか?(ここではわかりません。Javaで表示されますか?TCPプロトコルで直接処理するべきではありませんか?)
さて、非常に奇妙なことは、15分後(そして常に15分)、結果が受信され、ソケットが閉じられ、すべてが通常どおり続行されることです。
これは以前は常に機能していました。S
サーバーは別のデータセンターに移動したため、同じデータセンターW
にS
は存在しなくなりました。また、S
ファイアウォールの背後にあります。すべてのポートはとの間で承認される必要がありますS
(W
私は言われています)。謎は本当に15分の遅れです。DDOSに対する何らかの保護になると思いましたか?
私はネットワークの専門家ではないので助けを求めましたが、誰も助けてくれません。Wireshark(以前のEthereal)でパケットをキャプチャする男と30分間過ごしましたが、「セキュリティ上の理由」から、結果を確認できません。彼はこれを分析して私に戻らなければなりません。ファイアウォールログを要求しました。同じ話。
私はこれらのボックスのルートでも管理者でもありません。今、私は何をすべきかわかりません...皆さんからの解決策を期待していませんが、進歩する方法についてのいくつかのアイデアは素晴らしいでしょう!