Linux 实例常用内核网络参数介绍与常见问题处理
查看和修改 Linux 實例內核參數
方法一、通過?/proc/sys/?目錄
查看內核參數:使用?cat?查看對應文件的內容,例如執行命令?cat /proc/sys/net/ipv4/tcp_tw_recycle?查看?net.ipv4.tcp_tw_recycle?的值。
修改內核參數:使用?echo?修改內核參數對應的文件,例如執行命令?echo "0" > /proc/sys/net/ipv4/tcp_tw_recycle?將?net.ipv4.tcp_tw_recycle?的值修改為 0。
注意:
/proc/sys/?目錄是 Linux 內核在啟動后生成的偽目錄,其目錄下的?net?文件夾中存放了當前系統中開啟的所有內核參數、目錄樹結構與參數的完整名稱相關,如?net.ipv4.tcp_tw_recycle,它對應的文件是?/proc/sys/net/ipv4/tcp_tw_recycle,文件的內容就是參數值。
方法一修改的參數值僅在當次運行中生效,系統重啟后會回滾歷史值,一般用于臨時性的驗證修改的效果。若需要永久性修改,請參閱方法二。
方法二、通過?sysctl.conf?文件
查看內核參數:執行命令?sysctl -a?查看當前系統中生效的所有參數,如下所示:
net.ipv4.tcp_app_win?=?31 net.ipv4.tcp_adv_win_scale?=?2 net.ipv4.tcp_tw_reuse?=?0 net.ipv4.tcp_frto?=?2 net.ipv4.tcp_frto_response?=?0 net.ipv4.tcp_low_latency?=?0 net.ipv4.tcp_no_metrics_save?=?0 net.ipv4.tcp_moderate_rcvbuf?=?1 net.ipv4.tcp_tso_win_divisor?=?3 net.ipv4.tcp_congestion_control?=?cubic net.ipv4.tcp_abc?=?0 net.ipv4.tcp_mtu_probing?=?0 net.ipv4.tcp_base_mss?=?512 net.ipv4.tcp_workaround_signed_windows?=?0 net.ipv4.tcp_challenge_ack_limit?=?1000 net.ipv4.tcp_limit_output_bytes?=?262144 net.ipv4.tcp_dma_copybreak?=?4096 net.ipv4.tcp_slow_start_after_idle?=?1 net.ipv4.cipso_cache_enable?=?1 net.ipv4.cipso_cache_bucket_size?=?10 net.ipv4.cipso_rbm_optfmt?=?0 net.ipv4.cipso_rbm_strictvalid?=?1修改內核參數:
執行命令?/sbin/sysctl -w kernel.parameter="example"?修改參數,如sysctl -w net.ipv4.tcp_tw_recycle="0"。
執行命令?vi /etc/sysctl.conf?修改?/etc/sysctl.conf?文件中的參數。
執行命令?/sbin/sysctl -p?使配置生效。
注意:調整內核參數后內核處于不穩定狀態,請務必重啟實例。
Linux 網絡相關內核參數引發的常見問題及處理
Linux 實例 NAT 哈希表滿導致 ECS 實例丟包
此處涉及的內核參數:
net.netfilter.nf_conntrack_buckets
net.nf_conntrack_max
問題現象
ECS Linux 實例出現間歇性丟包,無法連接實例,通過?tracert、mtr?等工具排查,外部網絡未見異常。同時,如下圖所示,在系統日志中重復出現大量(table full, dropping packet.)錯誤信息。
Feb??6?16:05:07?i-***?kernel:?nf_conntrack:?table?full,?dropping?packet. Feb??6?16:05:07?i-***?kernel:?nf_conntrack:?table?full,?dropping?packet. Feb??6?16:05:07?i-***?kernel:?nf_conntrack:?table?full,?dropping?packet. Feb??6?16:05:07?i-***?kernel:?nf_conntrack:?table?full,?dropping?packet.原因分析
ip_conntrack 是 Linux 系統內 NAT 的一個跟蹤連接條目的模塊。ip_conntrack 模塊會使用一個哈希表記錄 TCP 協議 established connection 記錄,當這個哈希表滿了的時候,便會導致?nf_conntrack: table full, dropping packet錯誤。Linux 系統會開辟一個空間用來維護每一個 TCP 鏈接,這個空間的大小與?nf_conntrack_buckets、nf_conntrack_max?相關,后者的默認值是前者的 4 倍,而前者在系統啟動后無法修改,所以一般都是建議調大?nf_conntrack_max。
注意:系統維護連接比較消耗內存,請在系統空閑和內存充足的情況下調大?nf_conntrack_max,且根據系統的情況而定。
解決思路
使用管理終端登錄實例。
執行命令?# vi /etc/sysctl.conf?編輯系統內核配置。
修改哈希表項最大值參數:net.netfilter.nf_conntrack_max = 655350。
修改超時參數:net.netfilter.nf_conntrack_tcp_timeout_established = 1200,默認情況下 timeout 是 432000(秒)。
執行命令?# sysctl -p?使配置生效。
Time wait bucket table overflow 報錯
此處涉及的內核參數:
net.ipv4.tcp_max_tw_buckets
問題現象
Linux 實例?/var/log/message?日志全是類似?kernel: TCP: time wait bucket table overflow?的報錯信息,提示?time wait bucket table?溢出,如下:
Feb?18?12:28:38?i-***?kernel:?TCP:?time?wait?bucket?table?overflow Feb?18?12:28:44?i-***?kernel:?printk:?227?messages?suppressed. Feb?18?12:28:44?i-***?kernel:?TCP:?time?wait?bucket?table?overflow Feb?18?12:28:52?i-***?kernel:?printk:?121?messages?suppressed. Feb?18?12:28:52?i-***?kernel:?TCP:?time?wait?bucket?table?overflow Feb?18?12:28:53?i-***?kernel:?printk:?351?messages?suppressed. Feb?18?12:28:53?i-***?kernel:?TCP:?time?wait?bucket?table?overflow Feb?18?12:28:59?i-***?kernel:?printk:?319?messages?suppressed.執行命令?netstat -ant|grep TIME_WAIT|wc -l?統計處于 TIME_WAIT 狀態的 TCP 連接數,發現處于 TIME_WAIT 狀態的 TCP 連接非常多。
原因分析
參數?net.ipv4.tcp_max_tw_buckets?可以調整內核中管理 TIME_WAIT 狀態的數量,當實例中處于 TIME_WAIT 及需要轉換為 TIME_WAIT 狀態連接數之和超過了?net.ipv4.tcp_max_tw_buckets?參數值時,message 日志中將報錯?time wait bucket table,同時內核關閉超出參數值的部分 TCP 連接。您需要根據實際情況適當調高?net.ipv4.tcp_max_tw_buckets,同時從業務層面去改進 TCP 連接。
解決思路
執行命令?netstat -anp |grep tcp |wc -l?統計 TCP 連接數。
執行命令?vi /etc/sysctl.conf,查詢?net.ipv4.tcp_max_tw_buckets?參數。如果確認連接使用很高,容易超出限制。
調高參數?net.ipv4.tcp_max_tw_buckets,擴大限制。
執行命令?# sysctl -p?使配置生效。
Linux 實例中 FIN_WAIT2 狀態的 TCP 鏈接過多
此處涉及的內核參數:
net.ipv4.tcp_fin_timeout
問題現象
FIN_WAIT2 狀態的 TCP 鏈接過多。
原因分析
HTTP 服務中,Server 由于某種原因會主動關閉連接,例如 KEEPALIVE 超時的情況下。作為主動關閉連接的 Server 就會進入 FIN_WAIT2 狀態。
TCP/IP 協議棧中,存在半連接的概念,FIN_WAIT2 狀態不算做超時,如果 Client 不關閉,FIN_WAIT_2 狀態將保持到系統重啟,越來越多的 FIN_WAIT_2 狀態會致使內核 Crash。
建議調小?net.ipv4.tcp_fin_timeout?參數,減少這個數值以便加快系統關閉處于?FIN_WAIT2?狀態的 TCP 連接。
解決思路
執行命令?vi /etc/sysctl.conf,修改或加入以下內容:
net.ipv4.tcp_syncookies?=?1 net.ipv4.tcp_fin_timeout?=?30 net.ipv4.tcp_max_syn_backlog?=?8192 net.ipv4.tcp_max_tw_buckets?=?5000執行命令?# sysctl -p?使配置生效。
注意:由于?FIN_WAIT2?狀態的 TCP 連接會進入?TIME_WAIT?狀態,請同時參閱?time wait bucket table overflow 報錯。
Linux 實例中出現大量 CLOSE_WAIT 狀態的 TCP 連接
問題現象
執行命令?netstat -atn|grep CLOSE_WAIT|wc -l?發現當前系統中處于?CLOSE_WAIT?狀態的 TCP 連接非常多。
原因分析
關閉 TCP 連接時,TCP 連接的兩端都可以發起關閉連接的請求,若對端發起了關閉連接,但本地沒有關閉連接,那么該連接就會處于 CLOSE_WAIT 狀態。雖然該連接已經處于半開狀態,但是已經無法和對端通信,需要及時的釋放掉該鏈接。建議從業務層面及時判斷某個連接是否已經被對端關閉,即在程序邏輯中對連接及時關閉檢查。
解決思路
編程語言中對應的讀、寫函數一般包含了檢測 CLOSE_WAIT TCP 連接功能,例如:
Java 語言:
通過?read?方法來判斷 I/O 。當 read 方法返回?-1?時則表示已經到達末尾。
通過?close?方法關閉該鏈接。
C 語言:
檢查?read?的返回值。
若等于 0 則可以關閉該連接。
若小于 0 則查看 errno,若不是 AGAIN 則同樣可以關閉連接。
客戶端配置 NAT 后仍無法訪問 ECS 或 RDS 遠端服務器
此處涉及的內核參數:
net.ipv4.tcp_tw_recycle
net.ipv4.tcp_timestamps
問題現象
客戶端配置 NAT 后無法訪問遠端 ECS、RDS,包括配置了 SNAT 的 VPC ECS 。同時無法訪問連接其他 ECS 或 RDS 等云產品,抓包檢測發現遠端對客戶端發送的 SYN 包沒有響應。
原因分析
若遠端服務器的內核參數?net.ipv4.tcp_tw_recycle?和?net.ipv4.tcp_timestamps?的值都為 1,則遠端服務器會檢查每一個報文中的時間戳(Timestamp),若 Timestamp 不是遞增的關系,不會響應這個報文。配置 NAT 后,遠端服務器看到來自不同的客戶端的源 IP 相同,但 NAT 前每一臺客戶端的時間可能會有偏差,報文中的 Timestamp 就不是遞增的情況。
解決思路
遠端服務器為 ECS 時,修改參數?net.ipv4.tcp_tw_recycle?為 0。
遠端服務器為 RDS 等 PaaS 服務時。RDS 無法直接修改內核參數,需要在客戶端上修改參數?net.ipv4.tcp_tw_recycle?和?net.ipv4.tcp_timestamps?為 0。
文檔涉及的 Linux 內核參數說明
| net.ipv4.tcp_max_syn_backlog | 該參數決定了系統中處于?SYN_RECV?狀態的 TCP 連接數量。SYN_RECV?狀態指的是當系統收到 SYN 后,作了 SYN+ACK 響應后等待對方回復三次握手階段中的最后一個 ACK 的階段。 |
| net.ipv4.tcp_syncookies | 該參數表示是否打開 TCP 同步標簽(SYN_COOKIES),內核必須開啟并編譯 CONFIG_SYN_COOKIES,SYN_COOKIES?可以防止一個套接字在有過多試圖連接到達時引起過載。默認值 0 表示關閉。 當該參數被設置為 1 且?SYN_RECV?隊列滿了之后,內核會對 SYN 包的回復做一定的修改,即,在響應的 SYN+ACK 包中,初始的序列號是由源 IP + Port、目的 IP + Port 及時間這五個參數共同計算出一個值組成精心組裝的 TCP 包。由于 ACK 包中確認的序列號并不是之前計算出的值,惡意***者無法響應或誤判,而請求者會根據收到的 SYN+ACK 包做正確的響應。啟用?net.ipv4.tcp_syncookies后,會忽略?net.ipv4.tcp_max_syn_backlog。 |
| net.ipv4.tcp_synack_retries | 該參數指明了處于?SYN_RECV?狀態時重傳 SYN+ACK 包的次數。 |
| net.ipv4.tcp_abort_on_overflow | 設置該參數為 1 時,當系統在短時間內收到了大量的請求,而相關的應用程序未能處理時,就會發送 Reset 包直接終止這些鏈接。建議通過優化應用程序的效率來提高處理能力,而不是簡單地 Reset。 默認值: 0。 |
| net.core.somaxconn | 該參數定義了系統中每一個端口最大的監聽隊列的長度,是個全局參數。該參數和?net.ipv4.tcp_max_syn_backlog?有關聯,后者指的是還在三次握手的半連接的上限,該參數指的是處于 ESTABLISHED 的數量上限。若您的 ECS 實例業務負載很高,則有必要調高該參數。listen(2)?函數中的參數?backlog?同樣是指明監聽的端口處于 ESTABLISHED 的數量上限,當?backlog?大于?net.core.somaxconn時,以?net.core.somaxconn?參數為準。 |
| net.core.netdev_max_backlog | 當內核處理速度比網卡接收速度慢時,這部分多出來的包就會被保存在網卡的接收隊列上,而該參數說明了這個隊列的數量上限。 |
轉載于:https://blog.51cto.com/ycentos/2043834
總結
以上是生活随笔為你收集整理的Linux 实例常用内核网络参数介绍与常见问题处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux Shell编程之一循环结构
- 下一篇: linux 其他常用命令