4

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サーバーは別のデータセンターに移動したため、同じデータセンターWSは存在しなくなりました。また、Sファイアウォールの背後にあります。すべてのポートはとの間で承認される必要がありますSW私は言われています)。謎は本当に15分の遅れです。DDOSに対する何らかの保護になると思いましたか?

私はネットワークの専門家ではないので助けを求めましたが、誰も助けてくれません。Wireshark(以前のEthereal)でパケットをキャプチャする男と30分間過ごしましたが、「セキュリティ上の理由」から、結果を確認できません。彼はこれを分析して私に戻らなければなりません。ファイアウォールログを要求しました。同じ話。

私はこれらのボックスのルートでも管理者でもありません。今、私は何をすべきかわかりません...皆さんからの解決策を期待していませんが、進歩する方法についてのいくつかのアイデアは素晴らしいでしょう!

4

4 に答える 4

3

ローカルネットワークで問題なく機能した場合、これがプログラミングの問題であるとは思いません(flush()コメントについて)。

それ以外の場合、2 台のマシン間のネットワーク接続は正常ですか? (たとえば)FTP経由で同様の量のデータを問題なく転送できますか。適切なサイズのデータ​​のチャンクを送信するためだけにクライアント/サーバー スクリプトを組み合わせることで、この問題を再現できますか。つまり、W と S の間のネットワーク接続は良好ですか?

別の質問です。これで間にファイアウォールができました。これは、以前にはなかったボトルネックになる可能性がありますか? (ただし、一貫した 15 メートルの遅延がどのように説明されるかはわかりません)。

最後の質問。TCP 構成パラメーターの設定は何ですか (W と S の両方で - OS レベルのパラメーターについて考えています)。15mの数字を示唆する、またはそれにつながるものはありますか.

それが助けになるかどうかはわかりません。

于 2009-04-02T17:35:52.043 に答える
1

右。BufferedOutputStream を使用している場合は、最大バッファ サイズに達しない限り、flush() を呼び出す必要があります。

于 2009-04-02T15:25:31.763 に答える
1

ブライアンが言ったことを試すこととは別に、次のことも確認できます

1) いずれかのサーバーで tcpdump を実行し、ジョブが開始されてから遅延が発生し、すべての処理が完了するまでの一連のメッセージ フローを確認します。これにより、どちら側が遅延を引き起こしているかがわかります (W または S)。再送信、確認応答の欠落などがあるかどうかを確認します。

2) W と S の間で何らかのフラグメンテーションが発生していますか?

3) バイトがスタックしているサーバーのネットワーク負荷条件は? 負荷が高いために出力エラーが発生し、ソケット キューが空になっていませんか? (また、何らかのエラー状態に達した後、NIC バッファーがフラッシュされないか、送信の再開に失敗し、そのような状態がある種のウォッチドッグによってクリアされる NIC バグがある可能性もあります)

上記の2つに関する詳細情報は間違いなく役立ちます。

于 2009-04-03T04:27:33.910 に答える
0

読み取り呼び出しでスタックしたスレッドが、データを送信していたスレッドと同じであると確信していますか?実際に関与しているスレッドが他のアクティビティでブロックされ、スタックダンプにソケットI / Oを実行している他の無実のスレッドが表示される可能性はありますか?Javaを使用してからしばらく経ちましたが、IPC用のソケットを使用しているJVMを漠然と覚えています。

私はすべての受信側を調べて、そのうちの1つが意図した受信者であり、代わりに15分間何か他のことをしているのかどうかを確認します。

ある場所と別の場所で機能するという事実は、通常、データセンターの問題ではなく、アプリケーションのタイミングエラーを示しています。

于 2009-04-03T22:20:49.557 に答える