10Mbpsの速度で UDP パケットを受信しています。各パケットは、約1109 バイトで構成されます。したがって、 eth0で受信している1pkt/ms以上になります。Cのはパケットを受信し、そのパケットを Java に渡します。Java は、パケットのフィルタリングと必要な処理を行います。recvfrom()
ボトルネックは次のとおりです。
recvfrom()
遅すぎる: おそらく CPU を取得できないため、フェッチに 10 ミリ秒以上かかります。インターフェイス (JNI) を介して C から Java にパケットを渡すには、1 ~ 2 ミリ秒かかります。
Java 自体でのパケットの処理は、データベースの挿入または画像処理を行う必要があるかどうかによって、0.5 ~ 1 秒かかります。
したがって、問題は多くの遅延が積み重なり、半分以上のパケットが失われることです。
可能な解決策は次のとおりです。
C の必要性を
recvfrom()
完全に排除し、Java で UDP フェッチを直接実装します (注: そもそも、C の recvfrom() は、UDP ではなく生のパケットを受信するために実装されました)。この解決策により、JNI 転送の遅延が短縮される場合があります。Java で UDP 受信機能にマルチスレッドを実装します。ただし、マルチスレッドでは着信パケットの順序が保証されないため、シーケンスの UDP パケットに ID が必要になります。(ただし、この特定のプログラムでは、パケットを順序付けする必要があります)。このソリューションは、すべてのパケットを受信するのに役立つ可能性がありますが、データを送信するプロトコルを変更して、シーケンス識別子を追加する必要があります。マルチスレッドにより、受信側が CPU を取得する可能性が高くなり、パケットをすばやく取得できます。
Java では、着信パケットを格納する巨大なバッファとしてブロッキング キューを実装できます。Java パーサーは、このキューからのパケットを使用して処理できます。ただし、レシーバー機能が十分に高速で、パケットをドロップせずにすべての受信パケットをキューに入れるかどうかはわかりません。
どのソリューションが最適か、または上記のソリューションの組み合わせが機能するかを知りたいです。どんな助けや提案も大歓迎です。