web-dev-qa-db-ja.com

tcpdumpがパケットをログに記録した後にパケット損失が発生するのはなぜですか?

奇妙なパケット損失が発生したため、その理由を知りたいと思います。

イメージサーバーと、イメージサーバーにストレスをかけるためのサーバーがあります。どちらも同じデータセンターにあります

まず、次のような負荷テストを実行します(読みやすくするためにコマンドを短縮しました)。

ab -n 50 -c 5 http://testserver/img/de.png

画像のバイト数は約300バイトです。結果は非常に高速です。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:     1    3   0.7      3       4
Waiting:        1    3   0.7      3       3
Total:          1    3   0.7      3       4

同時実行性を増やすと、いくつかの遅れが見られます(読みやすくするためにコマンドが短縮されています)。

Sudo ab -n 500 -c 50 http://testserver/img/de.png

並行性50の結果:

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       1
Processing:     2   35 101.6     12     614
Waiting:        2   35 101.6     12     614
Total:          3   36 101.7     12     615

そのため、ほとんどのリクエストはかなり高速で、一部はかなり遅いことがわかります。

ネットワークトラフィック全体をtcpdumpでダンプしたところ、奇妙な再送信がいくつか見られました。

代替テキストhttp://vygen.de/screenshot1.png

このダンプはイメージサーバーで取得されました。

したがって、GET要求を含む最初のパッケージ(No. 306)がイメージサーバーに到着していることがわかりますが、tcpdumpがログに記録した後、パッケージが失われたようです。このパッケージはTomcatイメージサーバーに届かないようです。

再送信は、200ミリ秒後に要求元のサーバーによってトリガーされ、その後はすべて正常に実行されます。

パッケージを受け取った後に紛失する理由を知っていますか?

私たちのマシンは両方です:

  • Intel(R)Core(TM)i7 CPU 920 @ 2.67GHz
  • 8 GB RAM
  • イーサネットコントローラー:Realtek Semiconductor Co.、Ltd。RTL8111/8168B PCI Expressギガビットイーサネットコントローラー(rev 02)
  • Debianバージョン5.0.5

したがって、メモリやCPUの負荷に関しては問題ありません。

しばらく前に、NICコントローラーに問題が発生しました。別のドライバーを使用して処理しました。現在、r8169の代わりにr8168を使用しています。

しかし、Intel NIC-イーサネットコントローラー:Intel Corporation 82541PIギガビットイーサネットコントローラー(rev 05)でパケットが失われるという同じ問題がありました。

したがって、同じマシンでも異なるイーサネットカードでも同じ問題が発生します。

今まで私は、パケットが破損したときなど、回線上のサーバー間でのみパケット損失が発生すると考えていました。

Tcpdumpがパケットをログに記録した後、これらのパケット損失が発生する理由を知りたいのです。

あなたの助けは非常にありがたいです。

1
Janning

これの根本的な原因を見つけました。 Tomcatserver.xmlに25のacceptCountがありました。

acceptCountは、次のように文書化されています。

acceptCount

可能なすべての要求処理スレッドが使用されている場合の、着信接続要求の最大キュー長。キューがいっぱいになったときに受信したリクエストはすべて拒否されます。デフォルト値は100です。

しかし、これはacceptCountのすべてではありません。短い:acceptCountは、ソケットを開くときのバックログパラメータです。したがって、すべてのスレッドがビジーであるとは限らない場合でも、この値はリッスンバックログにとって重要です。リクエストの受信が速い場合、Tomcatはリクエストを受け入れて待機中のスレッドに委任できることが重要です。デフォルトのacceptCountは100です。これは、リクエストの突然のピークをフィードするための小さな値です。

Apacheとnginxで同じことを確認したところ、同じ奇妙なパケット損失が発生しましたが、同時実行性の値が高くなっています。 Apacheの対応する値はListenBacklogで、デフォルトは511です。

しかし、debian(および他のLinuxベースのOS)では、バックログパラメータのデフォルトの最大値は128です。

$ sysctl -a | grep somaxc
net.core.somaxconn = 128

したがって、acceptCountまたはListenBacklogに入力するものは何でも、net.core.somaxconnを変更するまで128を超えることはありません。

非常に忙しいWebサーバーの場合、128では不十分です。必要に応じて、500、1000、3000などに変更する必要があります。

AcceptCountを1000に設定し、net.core.somaxconnを1000に設定した後、これらのドロップされたパケットはなくなりました。 (現在、どこかにボトルネックがありますが、これは別の話です。)

1
Janning

200msがデフォルトですTCP再送信タイムアウト(RTO; RFC2988 で説明されていますが、最小値は定義されていません)。

つまり... RTOがヒットするように、何かが遅れたり失われたりしています。おそらく、RTOがトリガーされるようにパケットが遅延しましたが、wiresharkは、パケットの分析/レンダリング中にそれをスムーズにしましたか?トレースをより詳細に調査する必要があります。

パケットキャプチャのより大きな画像を提供できますか?

0
medina