前言
春節假期時學習了下內核參數與nginx的調優
最近因爲同事遇到問題一直沒有解,自己利用晚上時間再次進行驗證.
這裏將幾個參數的理解和驗證結果簡單總結一下.
希望能夠在學習的過程中將問題解決掉.
其實很後悔沒有好好學習代碼.現在很多問題都已經到了瓶頸期
無法深入的研究下去.
參數一
- net.ipv4.tcp_max_tw_buckets
先說一下基本的結論:
CentOS默認的值: 262144
阿里雲虛擬機的默認值: 5000
華爲雲虛擬機的默認值: 5000
騰訊雲虛擬機的默認值: 131072
在簡單描述一下這個參數的作用:
在 TIME_WAIT 數量等於 tcp_max_tw_buckets 時,
不會有新的 TIME_WAIT 產生。
類似 Nginx 之類的中間代理一定要關注這個值,因爲它對你的系統起到一個保護的作用,
一旦端口全部被佔用,服務就異常了。
tcp_max_tw_buckets 能幫你降低這種情況的發生概率,爭取補救時間。
學習來源: https://www.jianshu.com/p/b7e991be0909
我這邊理解就類似於 JVM裏面GC over limited的處理機制相仿.
能夠快速重用部分端口, 避免無端口可用無法建立新連接.
參數二
- net.ipv4.ip_local_port_range
這個參數 雲計算和CentOS的默認值出奇的一致:
32768 60999
第一個參數代表隨機端口的下限
第二個參數代表建立TCP連接時端口的上限
C10K甚至是C100K的很多優化裏面都是需要改這個參數的
TCP是有四元素 local_ip local_port remote_ip remote_port
來唯一確認一個TCP連接的.
理論上一個TCP的LISTEN的監聽端口可以建立很多個TCP連接的.
參數三
個人感覺這個參數其實是存在一定風險的
可能會導致錯誤的TCP連接.
但是理論上 linux內核有TCP狀態的檢驗還有TCP的序列號進行串行化處理
幾乎零可能性的出現嚴重的數據問題.
一個簡單的進行驗證的腳本
echo "443:" `netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 884 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep :443 |awk '{++state[$6]} END {for(key in state) print key,state[key]}'`
echo "5000:" `netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 884 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep :5000 |awk '{++state[$6]} END {for(key in state) print key,state[key]}'`
echo "5200:" `netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 884 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep :520 |awk '{++state[$6]} END {for(key in state) print key,state[key]}'`
可以定量分析不同端口的連接信息.
內核參數的驗證-1
修改內核參數
sysctl -w "net.ipv4.tcp_max_tw_buckets=50000"
登錄系統進行分析查看time wait的TCP數量.
[[email protected] ~]# netstat -anop |grep tcp |grep -v LISTEN |grep -v :637 |grep -v :884 |grep -v :1521 |grep -v tcp6 |grep -v :22 |grep :5200
tcp 0 0 10.110.139.230:5200 10.110.136.50:57506 TIME_WAIT - timewait (0.71/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:37506 TIME_WAIT - timewait (57.65/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:37604 TIME_WAIT - timewait (57.94/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:57490 TIME_WAIT - timewait (0.70/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:37708 TIME_WAIT - timewait (58.02/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:37696 TIME_WAIT - timewait (58.02/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:37630 TIME_WAIT - timewait (57.96/0/0)
tcp 0 0 10.110.139.230:5200 10.110.136.50:57538 TIME_WAIT - timewait (0.75/0/0)
發現會有40條 time wait的 tcp連接.
最後一列是等待終結的time wait的tcp連接 等到所有的連接都停止後再次修改內核參數
sysctl -w "net.ipv4.tcp_max_tw_buckets=10"
# 注意我這種修改僅是驗證問題, 沒有生產適用性.
# 注意每次測試至少要等待60秒等待之前的tcp連接終結.
再次執行登錄簡單測試,效果爲:
[[email protected] ~]# netstat -anop |grep tcp |grep -v LISTEN |grep -v :637 |grep -v :884 |grep -v :1521 |grep -v tcp6 |grep -v :22 |grep :5200
tcp 0 0 10.110.139.230:5200 10.110.136.50:59150 ESTABLISHED 716321/nginx: worke off (0.00/0/0)
發現沒有再次生成 time wait的連接
# 注意這個參數是整個操作系統所有的time_wait的連接數 不單純是一個端口的. 所以10個肯定是不夠用的.
內核參數驗證-2
直接修改參數:
sysctl -w "net.ipv4.ip_local_port_range=3000 4000"
# 注意結果可以與內核參數驗證-1 裏面的結果進行對照.
# 注意需要修改回 bucket的數據避免測試失效.
[[email protected] nginx]# netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 8848 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep 10.110.139.230
tcp 0 0 10.110.136.50:3508 10.110.139.230:5200 ESTABLISHED 3872246/nginx: work off (0.00/0/0)
tcp 0 0 10.110.136.50:31062 10.110.139.230:5200 TIME_WAIT - timewait (51.06/0/0)
注意可以再次修改一下 端口信息再次進行驗證
sysctl -w "net.ipv4.ip_local_port_range=5000 5100"
測試結果爲:
[[email protected] nginx]# netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 8848 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep 10.110.139.230
tcp 0 0 10.110.136.50:5096 10.110.139.230:5200 ESTABLISHED 3872246/nginx: work off (0.00/0/0)
tcp 0 0 10.110.136.50:3508 10.110.139.230:5200 TIME_WAIT - timewait (55.94/0/0)
僅僅是執行了一下刷新動作.
就會看到上面一個3508 local 的本地端口開始進入time_wait狀態
新建立的連接的local_port 就是 5096
sysctl -w "net.ipv4.ip_local_port_range=5000 5050"
效果也是完全一致符合猜測.
[[email protected] nginx]# netstat -anop |grep tcp |grep -v LISTEN |grep -v 637 |grep -v 8848 |grep -v 1521 |grep -v tcp6 |grep -v :22 |grep 10.110.139.230
tcp 0 0 10.110.136.50:5096 10.110.139.230:5200 TIME_WAIT - timewait (56.10/0/0)
tcp 0 0 10.110.136.50:5008 10.110.139.230:5200 ESTABLISHED 3872246/nginx: work off (0.00/0/0)
# 需要注意 修改改端口僅影響 第四列的本地連接信息, 不會影響第五列的外部連接信息
# 外部的需要是一個 監聽端口爲主.