-1

10Mbpsの速度で UDP パケットを受信して​​います。各パケットは、約1109 バイトで構成されます。したがって、 eth0で受信している1pkt/ms以上になります。Cのはパケットを受信し、そのパケットを Java に渡します。Java は、パケットのフィルタリングと必要な処理を行います。recvfrom()

ボトルネックは次のとおりです。

  1. recvfrom()遅すぎる: おそらく CPU を取得できないため、フェッチに 10 ミリ秒以上かかります。

  2. インターフェイス (JNI) を介して C から Java にパケットを渡すには、1 ~ 2 ミリ秒かかります。

  3. Java 自体でのパケットの処理は、データベースの挿入または画像処理を行う必要があるかどうかによって、0.5 ~ 1 秒かかります。

したがって、問題は多くの遅延が積み重なり、半分以上のパケットが失われることです。

可能な解決策は次のとおりです。

  1. C の必要性をrecvfrom()完全に排除し、Java で UDP フェッチを直接実装します (注: そもそも、C の recvfrom() は、UDP ではなく生のパケットを受信するために実装されました)。この解決策により、JNI 転送の遅延が短縮される場合があります。

  2. Java で UDP 受信機能にマルチスレッドを実装します。ただし、マルチスレッドでは着信パケットの順序が保証されないため、シーケンスの UDP パケットに ID が必要になります。(ただし、この特定のプログラムでは、パケットを順序付けする必要があります)。このソリューションは、すべてのパケットを受信するのに役立つ可能性がありますが、データを送信するプロトコルを変更して、シーケンス識別子を追加する必要があります。マルチスレッドにより、受信側が CPU を取得する可能性が高くなり、パケットをすばやく取得できます。

  3. Java では、着信パケットを格納する巨大なバッファとしてブロッキング キューを実装できます。Java パーサーは、このキューからのパケットを使用して処理できます。ただし、レシーバー機能が十分に高速で、パケットをドロップせずにすべての受信パケットをキューに入れるかどうかはわかりません。

どのソリューションが最適か、または上記のソリューションの組み合わせが機能するかを知りたいです。どんな助けや提案も大歓迎です。

4

2 に答える 2

2

このバーストはどのくらい続いていますか?それは継続的で永遠に続くのでしょうか?次に、負荷を処理できるより強力なハードウェアが必要です。おそらく、複数のサーバーが着信データを処理する負荷分散。

バーストは、せいぜい 1 秒か 2 秒のように、短い時間しか持続しませんか? 次に、下位レベルにすべてのパケットをできるだけ速く読み取らせ、キューに入れ、上位レベルに独自の時間でキューからメッセージを取得させます。

于 2016-03-02T13:07:23.390 に答える
0

ブロッキング モードでソケットを呼び出している可能性があるようですrecvfrom()。この場合、次のパケットが到着するまで返されません。パケットが 10 ミリ秒間隔で送信されている場合、おそらく送信側の遅延が原因で、ブロッキングrecvfrom()コールのループはそれぞれ 10 ミリ秒かかっているように見えます。ソケットをノンブロッキングに設定し、select()いつ呼び出すかを決定するようなものを使用します。次に、すべてをプロファイリングして、実際のボトルネックがどこにあるかを確認します。私の賭けは、JNI パススルーの 1 つまたは複数にかかっています。

recvfrom()「C」関数ではなく、システムコールであることに注意してください。Java の関数は、その上にレイヤーを追加するだけです。

于 2016-03-02T20:46:13.133 に答える