5

私はJBoss+EJBベースのエンタープライズアプリケーションの一部を開発しています。私のモジュールは、大量の着信UDPパケットを処理する必要があります。負荷テストを行ったところ、11ミリ秒間隔でパケットを送信した場合はすべて問題ないようですが、10ミリ秒間隔の場合は一部のパケットが失われます。私の意見ではかなり奇妙ですが、10 / 11msの間隔の負荷テストの比較を数回行ったところ、常に同じ結果になりました(10ms-いくつかの「失われた」パケット、11ms-すべてが正常です)。

同期に問題がある場合は、11msのテスト(少なくとも1つのパケットが失われたか、少なくとも1つの間違ったカウンター値)の場合にも表示されると思います。したがって、同期が原因でない場合は、パケットを受信するDatagramSocketが期待どおりに機能しない可能性があります。

受信バッファサイズ(SO_RCVBUF)のデフォルト値は57344であることがわかりました(おそらく、基になるIOネットワークバッファに依存します)。このバッファがいっぱいになると、新しい着信UDPデータグラムが拒否される可能性があります。この値をもう少し高く設定しようとしましたが、誇張すると、バッファがデフォルトのサイズに戻ることに気付きました。基盤となるレイヤーに依存している場合、JBossレベルから特定のOS /ネットワークカードの最大バッファーサイズを確認するにはどうすればよいですか?

受信バッファサイズが原因である可能性はありますか、または57344値がほとんどの場合を処理するのに十分な大きさである可能性がありますか?そのような問題の経験はありますか?

DatagramSocketにタイムアウトが設定されていません。私のUDPデータグラムには約70バイトのデータが含まれています(データグラムヘッダーを含まない値)。

[編集 済み]CiscoNetflowデータを受信するため、UDPを使用する必要があります。UDPは、ネットワークデバイスがトラフィック統計を送信するために使用するプロトコルです。また、送信バイト形式には影響しません(たとえば、パケットのカウンターを追加できないなど)。すべてのパケットが処理されるとは限りませんが(一部のデータグラムが失われる可能性があります)、ほとんどのパケットを処理することを期待しています。10ms間隔のテスト中に、パケットの約30%が失われました。

処理が遅いとこの問題が発生する可能性はほとんどありません。現在、シングルトンコンポーネントは、ループ内でreceiveメソッドを呼び出すDatagramSocketへの参照を保持しています。パケットが受信されると、キューに渡され、プールのステートレスコンポーネントから選択されて処理されます。「ファサード」シングルトンは、パケットを受信して​​処理に渡すことのみを担当します(完了イベントの処理を待機しません)。

よろしくお願いします、Piotr

4

4 に答える 4

5

UDPは配信を保証しないため、パラメーターを微調整することはできますが、特に非常に大規模なデータ転送の場合は、メッセージが配信されることを保証できません。

配信を保証する必要がある場合は、代わりにTCPを使用する必要があります。

UDPを使用する必要がある(または使用したい)場合は、各パケットを番号でエンコードし、予想されるパケット数を送信することもできます。たとえば、10個の大きなパケットを送信した場合、パケット1/10、パケット2/10などの情報を含めることができます。これにより、少なくともすべてのパケットを受信して​​いないかどうかを判断できます。それらを受信して​​いない場合は、欠落しているパケットを再送信する要求を送信できます。

于 2011-02-23T18:40:34.200 に答える
3

UDPは本質的に信頼性がありません。

データグラムは、コードより下のレベルのレシーバー内であっても、送信者とレシーバーの間の任意のポイントで破棄できます。recvバッファーをより大きなサイズに設定すると、マシン内のネットワークコードがより多くのデータグラムをバッファーするのに役立つ可能性がありますが、いずれにせよ一部のデータグラムが失われることを期待する必要があります。

recvロジックに時間がかかりすぎる場合(つまり、新しいデータグラムが到着するのにかかる時間よりも長い場合)、常に遅れが生じ、最終的には常にデータグラムが失われます。あなたができることは、recvコードができるだけ速く実行されることを確認することです。おそらく、インバウンドデータグラムをキューに移動し、それを「後で」または別のスレッドで処理します。成長し続けるキュー。

[編集をやり直してください...]そして、キューを処理しているのは何ですか?また、プロデューサーとコンシューマーの間でロックはどのように機能しますか?コードを変更して、recvロジックが単純にカウントをインクリメントし、データを破棄してループバックし、失われるデータグラムが少なくなるかどうかを確認します。いずれにせよ、UDPは信頼性が低く、破棄されるデータグラムがあり、それを予期して処理する必要があります。それについて心配することは、あなたが間違った問題に集中していることを意味します。取得したデータを利用し、そのデータをあまり取得しないと想定します。そうすれば、ネットワークが混雑してデータグラムのほとんどが破棄されても、プログラムは機能します。

要約すると、UDPではそれがまさにその通りです。

于 2011-02-23T19:03:12.550 に答える
2

テストでは、バッファに含めることができるパケットは2つまでであるように見えるため、各パケットが28KB未満の場合は、これで問題ありません。

ご存知のとおり、UDPは不可逆ですが、10ミリ秒ごとに複数のパケットを送信できるはずです。パケットをリッスンするだけの単純なレシーバーを作成して、そのアプリケーションがネットワーク/OSレベルであるかどうかを判断することをお勧めします。(後で疑う)

于 2011-02-23T18:41:36.347 に答える
1

Javaはわかりませんが、APIを使用すると、データグラムの非同期リッスン/レシーブを呼び出すことができますか?

  • O / S APIを使用して受信を実行します(アプリケーションレベルのバッファーをパラメーターとして渡します)
  • (受け取るものがない間待ってください...)
  • (O / Sはネットワークから何かを受信します...)
  • O / Sは、受信したパケットをバッファに入れ、API呼び出しを完了/返します

それが本当なら、API呼び出しの複数の同時インスタンスを実行して、複数のパケットを受信できる複数の同時アプリケーションレベルのバッファーが存在するようにすることをお勧めします。

于 2011-02-23T18:47:14.017 に答える