歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

當流量尖峰到達時,在Linux內核中解決網絡問題

幾周前,我們開始注意位於華盛頓的追蹤API的服務器網絡流量有很大的變化。從一個相當穩定的日常模式下,我們開始看到300-400 Mbps尖峰流量,但我們的合法的流量(事件和人為更新)是不變的。

突然,我們的網絡流量開始飙升像瘋了似的。

找到虛假的流量來源是當務之急,因為這些尖峰流量正觸發我們的上游路由器啟動DDOS減災模式來阻止流量。

有一些很好的內置的Linux工具幫助診斷網絡問題。

  • ifconfig 會顯示你的網絡接口和多少數據包通過他們

  • ethtool -S 會顯示你的數據包流的一些更詳細的信息,象在網卡級丟棄的數據包的數量。

  • iptables -L -v -n 將顯示你的各種防火牆規則處理數據包數。

  • netstat -s 會告訴由內核網絡協議棧維護的一大堆的計數器值,例如ACK的數量,重發的數量等。

  • sysctl -a | grep net.ip 將顯示你所有kernel中網絡相關的設置。

  • tcpdump 將顯示進出包的內容。

解決問題的線索是使用netstat -s命令的輸出。 不幸的是,當你檢查這個命令的輸出的時候,還很難告訴這些數字意味著什麼,應該是什麼,以及它們是如何改變的。為了檢查他們是如何變化的,我們創建了一個小程序來顯示連續運行命令的輸出,這讓我們了解各種計數器變化的快慢。有一行輸出看起來特別令人擔憂。

此計數器的通常速率在未受影響的服務器上一般是 30-40 /秒,所以我們知道肯定是哪裡出問題了。計數器表明我們正拒絕大量的包,因為這些包含有無效的 TCP 時間戳。臨時的快速解決方案是用下面的命令關閉 TCP 時間戳:

sysctl -w net.ipv4.tcp_timestamps=0

這立即導致了包風暴停止。但是這不是一個永久性的解決方案,因為 TCP 時間戳是用於測量往返時間和分配數據包流中的延遲包到正確位置。在高速連接的時候這將成為一個問題,TCP 序列號可能在數秒間隔內纏繞。關於 TCP 的時間戳和性能的詳細信息,請看 RFC 1323。

在 Mixpanel,每當我們看到異常流量模式的時候,我們一般也運行 tcpdump,這樣我們能夠分析流量,然後試圖確定根本原因。我們發現大量的 TCP ACK 數據包在我們的 API 服務器和一個特定的 IP 地址之間來回發送。結果我們的服務器陷入到向另一台服務器來來回回發送 TCP ACK 包的無限循環裡面。一個主機持續地發出 TCP 時間戳,但是另一主機卻不能識別這是有效的時間戳。

這時,我們意識到我們正在處理一個只能在 Linux 內核的 TCP 協議棧才能解決問題。所以我們的 CTO求助於 linux-netdev 看看是否能找到一個解決方案。值得慶幸的是我們發現這個問題已經遇到過的,並且有一個解決方案。原來,這種類型的包風暴可以由一些硬件故障或第三方改變 TCP SEQ,ACK,或連接中的主機認為對方發送過期的數據包所觸發。避免讓這種情況變成一個包風暴的方法是限制速度,設置 Linux 發送重復的 ACK 數據包速度為每秒一個或兩個。這裡有一個非常好的解釋。

我們將接受這個補丁而且將之移植到當前正在使用的Ubuntu(Trusty)內核當中。感謝Ubuntu讓這一切變得非常簡單,重新編譯修補過的內核僅僅只需要運行下面的命令,安裝生成的.deb包並重啟系統。

# 下載內核源代碼並構建依賴
apt-get build-dep linux-image-3.13.0-45-generic
apt-get source linux-image-3.13.0-45-generic
# 應用補丁
cd linux-lts-trusty-3.13.0/
patch -p1 < Mitigate-TCP-ACK-Loops.patch
# 構建內核
fakeroot ./debian/rules clean
fakeroot ./debian/rules binary-headers binary-generic

譯文:http://www.oschina.net/translate/diagnosing-networking-issues-in-the-linux-kernel

Copyright © Linux教程網 All Rights Reserved