TCP 零視窗大小和完整視窗大小
我們面臨的問題是一些http連接的響應時間> 60s(大約5%)。我發現問題應該在 Web 伺服器和負載均衡器之間。
這是我的發現,我們嘗試了兩組伺服器:
Setup A:只有 1 個 web 伺服器(Server A),所有的 tcp 流量都直接指向這個伺服器。
設置 B:負載均衡器 + 伺服器 A,伺服器 A 的權重為 100。使用算法“具有持久 IP 的輪詢”
對於Setup A,tcp連接確實很穩定,超時率不到1%,但是對於setup B,超時率超過5%,問題就出在這裡。(客戶端設置的連接超時為60s)
我們已經在一個公共環境中測試了這兩個設置(在 10 分鐘的時間範圍內),它們具有最接近的數據包數(大約 700,000 個數據包)和流量。結果,我們得到了 2 組 tcpdump,我發現了一些奇怪的日誌條目並將它們統計如下:
Setup A Setup B TCP Zero window size 0 611 TCP Window Full 0 3672 TCP Out-Of-Order 4147 4577 TCP Retransmission 23665 21551 TCP Dup Ack 10592 10121
對於上面的結果,我很確定這個關於 TCP 視窗的問題,所以我嘗試啟用 net.ipv4.tcp_window_scaling > reboot,但這沒有幫助。我也試過禁用 iptables,也沒有幫助。我不知道是否有任何配置影響 TCP 視窗。
值得知道的是,我們的負載均衡器 ip 是 xx.xx.117.128,所有標記為 TCP Window Full 的數據包都是從伺服器 A 到 xx.xx.117.25 並且所有標記為 TCP 零視窗大小的數據包都來自 xx.xx .117.25 到伺服器 A
我問過softlayer技術人員xx.xx.117.25是什麼,他們說“xx.xx.117.25是負載均衡器連接到你的真實伺服器的地址”他們猜這是防火牆問題,正如我上面提到的,我已經在關閉 iptables 的情況下進行了測試。所以我們可以消除這個因素
這就是我迄今為止發現的。
也許您對 sysctl 配置感興趣,它是:
net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 kernel.shmall = 4294967296 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_window_scaling = 1 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_max_syn_backlog = 1000 net.core.netdev_max_backlog = 1000 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_fin_timeout = 20
這是設置 A 中伺服器 A 的 tcp 狀態的快照
604 TIME_WAIT 7 SYN_RECV 1 LISTEN 2 FIN_WAIT1 1 ESTABLISHED 1 CLOSING
不太清楚為什麼 TIME_WAIT 這麼高(我有 tcp_tw_reuse 和 tcp_tw_recycle) 我也監控了 Setup B 上的 tcp 狀態,TIME_WAIT 的數量更少(大約 300 - 400)
對於 apache 配置:
KeepAlive Off <IfModule prefork.c> StartServers 5 MinSpareServers 10 MaxSpareServers 50 ServerLimit 500 MaxClients 500 MaxRequestsPerChild 4000 </IfModule>
請幫忙。非常感謝
您是否嘗試過沒有
tcp_tw_recycle
和tcp_tw_reuse
選項的設置?至少tcp_tw_recycle
會導致負載平衡器出現問題。此外,狀態中的套接字數量
TIME_WAIT
應該不是問題,因為它遠不及 30k,這是 Linux 中可用的預設埠數。如果要確保有足夠的埠可用,可以將
net.ipv4.ip_local_port_range
sysctl 設置為1024 65535
.