防火墻
如果系統防火墻丟包,表現的行為一般是所有的 UDP 報文都無法正常接收,當然不排除防火墻只 drop 一部分報文的可能性。
如果遇到丟包比率非常大的情況,請先檢查防火墻規則,保證防火墻沒有主動 drop UDP 報文。
UDP buffer size 不足
linux 系統在接收報文之后,會把報文保存到緩存區中。因為緩存區的大小是有限的,如果出現 UDP 報文過大(超過緩存區大小或者 MTU 大小)、接收到報文的速率太快,都可能導致 linux 因為緩存滿而直接丟包的情況。
在系統層面,linux 設置了 receive buffer 可以配置的最大值,可以在下面的文件中查看,一般是 linux 在啟動的時候會根據內存大小設置一個初始值。
- /proc/sys/net/core/rmem_max:允許設置的 receive buffer 最大值
- /proc/sys/net/core/rmem_default:默認使用的 receive buffer 值
- /proc/sys/net/core/wmem_max:允許設置的 send buffer 最大值
- /proc/sys/net/core/wmem_dafault:默認使用的 send buffer 最大值
但是這些初始值并不是為了應對大流量的 UDP 報文,如果應用程序接收和發送 UDP 報文非常多,需要講這個值調大??梢允褂?sysctl
命令讓它立即生效:
sysctl -w net.core.rmem_max=26214400 # 設置為 25M
也可以修改 /etc/sysctl.conf
中對應的參數在下次啟動時讓參數保持生效。
如果報文報文過大,可以在發送方對數據進行分割,保證每個報文的大小在 MTU 內。
另外一個可以配置的參數是 netdev_max_backlog
,它表示 linux 內核從網卡驅動中讀取報文后可以緩存的報文數量,默認是 1000,可以調大這個值,比如設置成 2000:
sudo sysctl -w net.core.netdev_max_backlog=2000
系統負載過高
系統 CPU、memory、IO 負載過高都有可能導致網絡丟包,比如 CPU 如果負載過高,系統沒有時間進行報文的 checksum 計算、復制內存等操作,從而導致網卡或者 socket buffer 出丟包;memory 負載過高,會應用程序處理過慢,無法及時處理報文;IO 負載過高,CPU 都用來響應 IO wait,沒有時間處理緩存中的 UDP 報文。
linux 系統本身就是相互關聯的系統,任何一個組件出現問題都有可能影響到其他組件的正常運行。對于系統負載過高,要么是應用程序有問題,要么是系統不足。對于前者需要及時發現,debug 和修復;對于后者,也要及時發現并擴容。
應用丟包
上面提到系統的 UDP buffer size,調節的 sysctl 參數只是系統允許的最大值,每個應用程序在創建 socket 時需要設置自己 socket buffer size 的值。
linux 系統會把接受到的報文放到 socket 的 buffer 中,應用程序從 buffer 中不斷地讀取報文。所以這里有兩個和應用有關的因素會影響是否會丟包:socket buffer size 大小以及應用程序讀取報文的速度。
對于第一個問題,可以在應用程序初始化 socket 的時候設置 socket receive buffer 的大小,比如下面的代碼把 socket buffer 設置為 20MB:
uint64_t receive_buf_size = 20*1024*1024; //20 MB
setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &receive_buf_size, sizeof(receive_buf_size));
如果不是自己編寫和維護的程序,修改應用代碼是件不好甚至不太可能的事情。很多應用程序會提供配置參數來調節這個值,請參考對應的官方文檔;如果沒有可用的配置參數,只能給程序的開發者提 issue 了。
很明顯,增加應用的 receive buffer 會減少丟包的可能性,但同時會導致應用使用更多的內存,所以需要謹慎使用。
另外一個因素是應用讀取 buffer 中報文的速度,對于應用程序來說,處理報文應該采取異步的方式
包丟在什么地方
想要詳細了解 linux 系統在執行哪個函數時丟包的話,可以使用 dropwatch
工具,它監聽系統丟包信息,并打印出丟包發生的函數地址:
# dropwatch -l kas
Initalizing kallsyms db
start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at tcp_v4_do_rcv+cd (0xffffffff81799bad)
10 drops at tcp_v4_rcv+80 (0xffffffff8179a620)
1 drops at sk_stream_kill_queues+57 (0xffffffff81729ca7)
4 drops at unix_release_sock+20e (0xffffffff817dc94e)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)
通過這些信息,找到對應的內核代碼處,就能知道內核在哪個步驟中把報文丟棄,以及大致的丟包原因。
此外,還可以使用 linux perf 工具監聽 kfree_skb
(把網絡報文丟棄時會調用該函數) 事件的發生:
sudo perf record -g -a -e skb:kfree_skb
sudo perf script
關于 perf 命令的使用和解讀,網上有很多文章可以參考。
總結
- UDP 本身就是無連接不可靠的協議,適用于報文偶爾丟失也不影響程序狀態的場景,比如視頻、音頻、游戲、監控等。對報文可靠性要求比較高的應用不要使用 UDP,推薦直接使用 TCP。當然,也可以在應用層做重試、去重保證可靠性
- 如果發現服務器丟包,首先通過監控查看系統負載是否過高,先想辦法把負載降低再看丟包問題是否消失
- 如果系統負載過高,UDP 丟包是沒有有效解決方案的。如果是應用異常導致 CPU、memory、IO 過高,請及時定位異常應用并修復;如果是資源不夠,監控應該能及時發現并快速擴容
- 對于系統大量接收或者發送 UDP 報文的,可以通過調節系統和程序的 socket buffer size 來降低丟包的概率
- 應用程序在處理 UDP 報文時,要采用異步方式,在兩次接收報文之間不要有太多的處理邏輯
參考資料
- Pivotal: Network troubleshooting guide
- What are udp “packet receive errors” and “packets to unknown port received”
- Lost multicast packets troubleshooting guide
- splunk Answers: UDP Drops on Linux
作者:吳偉
原文:
https://cizixs.com/2018/01/13/linux-udp-packet-drop-debug/
-
cpu
+關注
關注
68文章
10902瀏覽量
213013 -
TCP
+關注
關注
8文章
1378瀏覽量
79301 -
UDP
+關注
關注
0文章
327瀏覽量
34043 -
網絡驅動
+關注
關注
0文章
7瀏覽量
7423
發布評論請先 登錄
相關推薦
udp數據丟包的原因?
Linux應用的延時和丟包模擬
簡述linux系統UDP丟包問題分析思路(上)
![<b class='flag-5'>簡述</b><b class='flag-5'>linux</b><b class='flag-5'>系統</b><b class='flag-5'>UDP</b><b class='flag-5'>丟</b><b class='flag-5'>包</b>問題<b class='flag-5'>分析</b><b class='flag-5'>思路</b>(上)](https://file1.elecfans.com/web2/M00/83/C3/wKgZomRl7nuAHtSvAABuNG2NTaU434.jpg)
如何解決MPSoC萬兆以太網應用中UDP接收丟包問題
![如何解決MPSoC萬兆以太網應用中<b class='flag-5'>UDP</b>接收<b class='flag-5'>丟</b><b class='flag-5'>包</b>問題](https://file1.elecfans.com/web2/M00/89/A2/wKgZomSJIb6AazCYAAAJq9Qhy-g859.png)
Linux下模擬網絡時延和丟包神器介紹
![<b class='flag-5'>Linux</b><b class='flag-5'>下</b>模擬網絡時延和<b class='flag-5'>丟</b><b class='flag-5'>包</b>神器介紹](https://file1.elecfans.com/web2/M00/8B/E0/wKgaomShFM6ADnlCAAA3cN9z1oU196.png)
網絡丟包問題分析
![網絡<b class='flag-5'>丟</b><b class='flag-5'>包</b>問題<b class='flag-5'>分析</b>](https://file1.elecfans.com/web2/M00/AD/E7/wKgaomVRlkOAOCrnAAEyfVoOI9A319.jpg)
評論