全部產品
Search
文件中心

:ECS執行個體中的應用偶爾出現丟包現象並且核心日誌(dmesg)存在kernel: nf_conntrack: table full, dropping packet的報錯資訊

更新時間:Oct 12, 2024

問題描述

串連ECS執行個體中的應用時偶爾出現丟包現象。經排查,ECS執行個體的周邊網路正常,但核心日誌(dmesg)中存在kernel: nf_conntrack: table full, dropping packet的錯誤資訊。存在此問題的ECS執行個體符合如下條件。

  • 鏡像:aliyun-2.1903-x64-20G-alibase-20190327.vhd及之後的所有鏡像版本。

  • 核心:kernel-4.19.24-9.al7及以後的所有核心版本。

問題原因

nf_conntrack是Linux系統內NAT的一個跟蹤串連條目的模組。nf_conntrack模組會使用一個雜湊表記錄TCP協議established connection記錄,當這個雜湊表滿之後,新的串連會引發nf_conntrack: table full, dropping packet錯誤。關於nf_conntrack模組中的重要參數,可參考如下資訊。

  • nf_conntrack_buckets:雜湊表的大小,可在模組載入時指定參數,也可以通過sysctl命令修改。當系統記憶體大於等於4 GB時,它的預設值是65536。

  • nf_conntrack_max:雜湊表的最大節點個數,即nf_conntrack模組支援的最大串連數。當系統記憶體大於等於4 GB時,它的預設值是262144。對於處理大量已連線的服務器來說,該預設值相對較小。

  • nf_conntrack_tcp_timeout_time_wait:nf_conntrack模組中儲存time_wait狀態的TCP連線時間,預設值為120s。

解決方案

請您結合現場實際情況,從如下兩種解決方案中選擇最適合您業務情境的方法。

方案一:通過sysctl介面調整nf_conntrack模組中的參數值

業務側應提前自行確認應用程式可能使用的nf_conntrack最大串連數,並參考如下命令,通過sysctl介面調整nf_conntrack模組中的參數值。

sysctl -w net.netfilter.nf_conntrack_max=1503232
sysctl -w net.netfilter.nf_conntrack_buckets=375808  # 如果使用非4.19核心,該選項可能無法在運行時修改
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=60
重要

命令中的參數值僅供參考,現場請結合實際業務情況進行調整。在調整前,建議提前建立快照或備份重要檔案,確保資料安全。

說明

參數配置建議:

  • 如果您的業務本身符合并發串連數較高,其中主要是短串連的特性。建議增大nf_conntrack_maxnf_conntrack_buckets的參數值,以確保不會由於串連數過多導致nf_conntrack的雜湊表滿。一般建議nf_conntrack_max參數值為nf_conntrack_buckets參數值的4倍 。

  • 建議一起調整nf_conntrack_bucketsnf_conntrack_max參數。如果只改動nf_conntrack_max參數值,可能會導致雜湊表上的鏈表過長,查詢效率低。如果只改動nf_conntrack_buckets參數值,不能解決該問題。

  • 調整nf_conntrack_tcp_timeout_time_wait參數務必在理解其原理和可能影響的基礎上,結合實際應用情境和效能監測結果,謹慎實施;以下是一些業務情境參數配置參考:

    • 對於需要處理大量短期串連的高並發服務(如Web伺服器),可以考慮將nf_conntrack_tcp_timeout_time_wait設定為一個較短的時間,比如30秒或60秒。這樣可以更快地回收連接埠資源,支援更多新串連。但請確保您的應用程式能夠容忍潛在的少量資料重傳或延遲問題。

    • 如果您的應用對資料轉送的完整性有極高要求,比如金融交易系統,那麼保持預設或接近預設的nf_conntrack_tcp_timeout_time_wait時間可能是更安全的選擇,以確保所有資料包都能正確送達。

    • 在有較高網路延遲或不穩定的網路環境下,較短的nf_conntrack_tcp_timeout_time_wait時間可能增加資料丟失的風險,因此可能需要更保守的設定。

方案二:通過iptables過濾不需要追蹤的串連

您可以在iptables規則中增加-j notrack參數 ,即過濾不需要追蹤(track)的串連。該方式可以將不需要追蹤的串連直接進行notrack處理,不會佔用雜湊表的空間,也就不會引發報錯。

sudo iptables -t raw -A PREROUTING -p udp -j NOTRACK
sudo iptables -t raw -A PREROUTING -p tcp --dport 22 -j NOTRACK
說明

此處的命令表示不追蹤UDP和22連接埠的TCP串連,僅供參考。現場以實際情況為準。

相關文檔