為什麼數據位於 Send-Q 中?TCP 會話凍結
問題
我為 20-50 個使用者執行 IRC 伺服器。我們有時會遇到消息沒有及時到達或根本沒有到達的問題。在一些數據包擷取之後,我們確定消息位於伺服器的“Send-Q”中。當消息未到達時,我將查看“netstat -ct”輸出並看到如下內容:
Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 1756 ubuntu:ircd 10.8.1.7:63602 ESTABLISHED
有時,如果我等待幾分鐘,Send-Q 將變為 0 並且消息將被傳遞,有時客戶端超時。我的問題是,為什麼它不只是傳遞消息?是什麼導致他們在 Send-Q 中坐了這麼久?
sshd 也表現出類似的行為,我的 ssh 會話有時會凍結,有時會回來,有時會超時。
背景
不確定這裡的基礎設施是否與問題有關,所以看起來是這樣的:這些客戶端在 Windows 7 上,並與 OpenVPN 連接。OpenVPN 伺服器位於 PFSense 上,IRC 伺服器位於連接到 PFSense 的本地(NAT’d)LAN 上。我有一個防火牆規則,允許客戶端與伺服器上的 6667 通信。
正在調查…
延遲/損失- 看起來足夠好。不是最好的連結,但我認為這對於 IRC 和 SSH 來說會很好。這是從我的客戶端到伺服器的 ping,這是我的 IRC 和 SSH 間歇性掛起:
Ping statistics for 10.8.5.2: Packets: Sent = 4478, Received = 4460, Lost = 18 (0% loss)
以毫秒為單位的近似往返時間:最小值 = 17.2 毫秒,最大值 = 273.4 毫秒,平均值 = 32.3 毫秒
MSS/MTU 問題- MTU 似乎沒問題。我客戶端上的 OpenVPN mtu-test 說:
Thu Dec 03 12:41:21 2015 NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[1589,1589] remote->local=[1589,1589]
…這是我的手動測試:
> ping -f -l 1472 10.8.5.2 Pinging 10.8.5.2 with 1472 bytes of data: Reply from 10.8.5.2: bytes=1472 time=23ms TTL=63 > ping -f -l 1473 10.8.5.2 Pinging 10.8.5.2 with 1473 bytes of data: Packet needs to be fragmented but DF set.
頻寬/吞吐量- 進行了一些 iperf 測試以確保不存在吞吐量問題。再次,看起來足夠體面:
iperf -c 10.8.5.2 ------------------------------------------------------------ Client connecting to 10.8.5.2, TCP port 5001 TCP window size: 63.0 KByte (default) ------------------------------------------------------------ [ 3] local 10.8.0.23 port 18587 connected with 10.8.5.2 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 26.0 MBytes 21.8 Mbits/sec
謝謝,任何幫助理解“Send-Q”或更具體的關於這個問題的想法將不勝感激。讓我知道我是否可以在此處提供更多資訊。
更新
發現我實際上有大量的封包遺失。來自客戶端-> VPN 的 Ping 沒有顯示這一點,但在使用來自 VPN-> 客戶端的 fping 時非常明顯。我注意到它只是 Windows 客戶端,重新安裝最新的 OpenVPN 客戶端似乎已經修復了損失。它可能與通過磁碟映像安裝的 OpenVPN TAP 適配器有關。每台機器手動安裝似乎可以解決問題。
當應用程序將數據寫入其本地核心 TCP 堆棧時,數據進入發送隊列。當對方的 TCP 堆棧確認收到數據時,數據將從發送隊列中刪除。如果它們位於發送隊列中,則意味著您的 IRC 伺服器程式碼已將它們發送到您的核心,但連接的另一端尚未確認它們。這可能是因為它們尚未發送。這可能是由伺服器頻寬限製或伺服器性能限制引起的,但最常見的原因是對方接收數據的速度不如伺服器發送數據的速度快。