Tcp

為什麼在 tcpdump 記錄數據包後丟包?

  • August 24, 2010

我們遇到了一些奇怪的丟包,想知道這是什麼原因。

我們有一個圖像伺服器和一個用於對圖像伺服器施加壓力的伺服器。兩者都位於同一個數據中心

首先,我們執行這樣的負載測試(為了便於閱讀,命令被縮短):

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 請求的初始包(第 306 號)正在到達映像伺服器,但似乎在 tcpdump 記錄後該包失去了。在我看來,這個包沒有到達 tomcat 圖像伺服器。

請求伺服器在 200 毫秒後觸發重傳,之後一切正常。

您知道包裹收到後會失去的任何原因嗎?

我們的機器都是:

  • Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
  • 8 GB 記憶體
  • 乙太網控制器:Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express 千兆乙太網控制器(rev 02)
  • Debian 版本 5.0.5

所以我們沒有任何關於記憶體或cpu負載的問題。

不久前,我們的 nic 控制器出現了一些問題。我們使用不同的驅動程序來處理它,我們現在使用 r8168 而不是 r8169

但是我們在使用英特爾 NIC 時遇到了同樣的丟包問題 - 乙太網控制器:英特爾公司 82541PI 千兆乙太網控制器(rev 05)

所以我們看到相同的機器但不同的乙太網卡存在相同的問題。

到目前為止,我認為封包遺失只會發生線上上的伺服器之間,當數據包被損壞或類似的事情時。

我們真的很想知道在 tcpdump 記錄後這些封包遺失可能是什麼原因。

非常感謝您的幫助。

我們找到了這個問題的根本原因。我們的 tomcat server.xml 中的 acceptCount 為 25。

acceptCount 記錄如下:

接受計數

當所有可能的請求處理執行緒都在使用時,傳入連接請求的最大隊列長度。隊列已滿時收到的任何請求都將被拒絕。預設值為 100。

但這並不是關於 acceptCount 的全部內容。簡而言之:acceptCount 是打開套接字時的 backlog 參數。所以這個值對於監聽積壓很重要,即使不是所有執行緒都忙。如果請求更快進入然後tomcat可以接受並將它們委託給等待執行緒,這一點很重要。預設的 acceptCount 是 100。這仍然是一個很小的值,可以滿足請求的突然高峰。

我們用 apache 和 nginx 檢查了同樣的事情,並且有同樣奇怪的丟包,但並發值更高。apache 中對應的值為 ListenBacklog,預設為 511。

但是,對於 debian(和其他基於 linux 的作業系統),積壓參數的預設最大值是 128。

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

因此,無論您在 acceptCount 或 ListenBacklog 中輸入什麼,在您更改 net.core.somaxconn 之前它都不會超過 128

對於一個非常繁忙的網路伺服器,128 是不夠的。您應該根據需要將其更改為 500、1000 或 3000。

在將 acceptCount 設置為 1000 並將 net.core.somaxconn 設置為 1000 後,我們不再有那些丟棄的數據包。(現在我們在其他地方遇到了瓶頸,但這是另一個故事……)

引用自:https://serverfault.com/questions/165596