Javaサーバーアプリケーションがあります。
while(true)
{
serverSocket.receive(receivePacket);
process(receivePacket);
serverSocket.send(sendPacket);
try {
Thread.sleep(10000); // sleep for 10s
} catch (InterruptedException e) {
e.printStackTrace();
}
}
10秒あたり1つのUDPパケットを受信して処理します。
10個のUDPパケットをサーバーに送信すると、1個のパケットが処理されてから10秒間スリープ状態になります。そのため、100秒後に10番目のパケットの応答を受け取ります。
これにより、サーバー1はCentOSバージョン6.4(最終)を実行します。
Server 1: cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
110: 00000000:10AE 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 85635445 2 ffff880836e6d100 0
111: 00000000:10AF 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 85635446 2 ffff88083913a1c0 0
115: 00000000:15B3 00000000:0000 07 00000000:00004FC8 00:00000000 00000000 0 0 390649369 2 ffff880434ae7440 0
117: 02FE6341:0035 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 353480394 2 ffff8808367f9040 0
サーバー2で同じことを行うと、次のようになります。
Server 2: cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
4: FCA9C11F:C36F 8C719AC6:0035 01 00000000:00000000 00:00000000 00000000 0 0 2983494501 2 ffff880169aff4c0 0
5: FCA9C11F:D3F0 8C719AC6:0035 01 00000000:00000000 00:00000000 00000000 0 0 2983494485 2 ffff8801b9bbedc0 0
16: 7A52BB59:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438608536 2 ffff8807656764c0 0
16: A2EE0D55:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438608045 2 ffff88077ccdd7c0 0
16: A58F466D:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438607809 2 ffff8801129f6240 0
どちらもCentosサーバーであり、アプリケーションがサーバーに入ってくるデータよりも遅いパケットを処理するため、server1のrx_queueバッファが増加していることがわかります。
私はserver2で同じことをしましたが、rx_queueはserver2で増加しません。私は何かが間違っているか、間違って理解しましたか?
ベストアンサー1
Ubuntu 18.04 LTS(カーネル4.15.0-38)でも同様の問題が発生します。しかし、私のDebian 9.5(カーネル4.9.110-3)コンピュータではこれは起こりません。最新のカーネルのバグだと思いますか?
問題を再現する簡単な方法は、netcatを使用することです。クライアントとサーバーはローカルであるか、別のシステムに存在できます。
- 端末でnetcatサーバーを実行する:nc -u -l 1234
- 他の端末でnetcatクライアントを実行する:nc -u 127.0.0.1 1234
- クライアントにテキストメッセージ「a」と入力し、Enter キーを押します。
- 3番目の端末でrecv -qの長さを確認してください。 netstat -plan regex 1234
Ubuntuでは、netcatがソケットからメッセージを読み取って印刷しても、受信udpソケットには空ではないrecv-q(2バイトメッセージの場合は768バイト)があります。私はrecv-qが約52kまで増加し続け、再びゼロにリセットされることを発見しました。
Debian では、UDP ソケットがパケットを受信できるよりも早く使い果たされるたびに、recv-q は常に 0 です。
また、次のカーネルのバグレポートも見つかりました。/proc/net/udp の UDP rx_queue が正しく計算されません。