100万并发连接服务器笔记之1M并发连接目标达成
第四個遇到的問題:tcp_mem
在服務端,連接達到一定數量,諸如50W時,有些隱藏很深的問題,就不斷的拋出來。 通過查看dmesg命令查看,發現大量TCP: too many of orphaned sockets錯誤,也很正常,下面到了需要調整tcp socket參數的時候了。
第一個需要調整的是tcp_rmem,即TCP讀取緩沖區,單位為字節,查看默認值
cat /proc/sys/net/ipv4/tcp_rmem 4096 87380 4161536默認值為87380bit ≈ 86K,最小為4096bit=4K,最大值為4064K。
第二個需要調整的是tcp_wmem,發送緩沖區,單位是字節,默認值
cat /proc/sys/net/ipv4/tcp_wmem 4096 16384 4161536解釋同上
第三個需要調整的tcp_mem,調整TCP的內存大小,其單位是頁,1頁等于4096字節。系統默認值:
cat /proc/sys/net/ipv4/tcp_mem 932448 1243264 1864896tcp_mem(3個INTEGER變量):low, pressure, high
- low:當TCP使用了低于該值的內存頁面數時,TCP不會考慮釋放內存。
- pressure:當TCP使用了超過該值的內存頁面數量時,TCP試圖穩定其內存使用,進入pressure模式,當內存消耗低于low值時則退出pressure狀態。
- high:允許所有tcp sockets用于排隊緩沖數據報的頁面量,當內存占用超過此值,系統拒絕分配socket,后臺日志輸出“TCP: too many of orphaned sockets”。
一般情況下這些值是在系統啟動時根據系統內存數量計算得到的。 根據當前tcp_mem最大內存頁面數是1864896,當內存為(1864896*4)/1024K=7284.75M時,系統將無法為新的socket連接分配內存,即TCP連接將被拒絕。
實際測試環境中,據觀察大概在99萬個連接左右的時候(零頭不算),進程被殺死,觸發out of socket memory錯誤(dmesg命令查看獲得)。每一個連接大致占用7.5K內存(下面給出計算方式),大致可算的此時內存占用情況(990000 * 7.5 / 1024K = 7251M)。
這樣和tcp_mem最大頁面值數量比較吻合,因此此值也需要修改。
三個TCP調整語句為:
echo "net.ipv4.tcp_mem = 786432 2097152 3145728">> /etc/sysctl.conf echo "net.ipv4.tcp_rmem = 4096 4096 16777216">> /etc/sysctl.conf echo "net.ipv4.tcp_wmem = 4096 4096 16777216">> /etc/sysctl.conf備注: 為了節省內存,設置tcp讀、寫緩沖區都為4K大小,tcp_mem三個值分別為3G 8G 16G,tcp_rmem和tcp_wmem最大值也是16G。
目標達成
經過若干次的嘗試,最終達到目標,1024000個持久連接。1024000數字是怎么得來的呢,兩臺物理機器各自發出64000個請求,兩個配置為6G左右的centos測試端機器(綁定7個橋接或NAT連接)各自發出640007 = 448000。也就是 1024000 = (64000) + (64000) + (640007) + (64000*7), 共使用了16個網卡(物理網卡+虛擬網卡)。?
終端輸出
在線用戶目標達到1024000個!
服務器狀態信息
服務啟動時內存占用:
total???????used???????free?????shared????buffers?????cachedMem:?????????10442????????271??????10171??????????0?????????22?????????78-/+ buffers/cache:????????171??????10271Swap:?????????8127??????????0???????8127系統達到1024000個連接后的內存情況(執行三次 free -m 命令,獲取三次結果):
total???????used???????free?????shared????buffers?????cachedMem:?????????10442???????7781???????2661??????????0?????????22?????????78-/+ buffers/cache:???????7680???????2762Swap:?????????8127??????????0???????8127total???????used???????free?????shared????buffers?????cachedMem:?????????10442???????7793???????2649??????????0?????????22?????????78-/+ buffers/cache:???????7692???????2750Swap:?????????8127??????????0???????8127total???????used???????free?????shared????buffers?????cachedMem:?????????10442???????7804???????2638??????????0?????????22?????????79-/+ buffers/cache:???????7702???????2740Swap:?????????8127??????????0???????8127 這三次內存使用分別是7680,7692,7702,這次不取平均值,取一個中等偏上的值,定為7701M。那么程序接收1024000個連接,共消耗了 7701M-171M = 7530M內存, 7530M*1024K / 1024000 = 7.53K, 每一個連接消耗內存在為7.5K左右,這和在連接達到512000時所計算較為吻合。?
虛擬機運行Centos內存占用,不太穩定,但一般相差不大,以上數值,僅供參考。
執行top -p?某刻輸出信息:
??? top - 17:23:17 up 18 min,??4 users,??load average: 0.33, 0.12, 0.11 Tasks:???1 total,???1 running,???0 sleeping,???0 stopped,???0 zombieCpu(s):??0.2%us,??6.3%sy,??0.0%ni, 80.2%id,??0.0%wa,??4.5%hi,??8.8%si,??0.0%stMem:??10693580k total,??6479980k used,??4213600k free,????22916k buffersSwap:??8323056k total,????????0k used,??8323056k free,????80360k cachedPID USER??????PR??NI??VIRT??RES??SHR S %CPU %MEM????TIME+??COMMAND??????????????????????2924 yongboy???20???0 82776??74m??508 R 51.3??0.7???3:53.95 server?執行vmstate:
vmstat procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 2725572 23008 80360 0 0 21 2 1012 894 0 9 89 2 0獲取當前socket連接狀態統計信息:
cat /proc/net/sockstat sockets: used 1024380 TCP: inuse 1024009 orphan 0 tw 0 alloc 1024014 mem 2 UDP: inuse 11 mem 1 UDPLITE: inuse 0 RAW: inuse 0 FRAG: inuse 0 memory 0獲取當前系統打開的文件句柄:
sysctl -a | grep file fs.file-nr = 1025216 0 1048576 fs.file-max = 1048576此時任何類似于下面查詢操作都是一個慢,等待若干時間還不見得執行完畢。
netstat -nat|grep -i "8000"|grep ESTABLISHED|wc -l netstat -n | grep -i "8000" | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'以上兩個命令在二三十分鐘過去了,還未執行完畢,只好停止。
小結
本次從頭到尾的測試,所需要有的linux系統需要調整的參數也就是那么幾個,匯總一下:
echo "yongboy soft nofile 1048576" >> /etc/security/limits.confecho "yongboy hard nofile 1048576" >>??/etc/security/limits.confecho "fs.file-max = 1048576" >> /etc/sysctl.confecho "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.confecho "net.ipv4.tcp_mem = 786432 2097152 3145728" >> /etc/sysctl.confecho "net.ipv4.tcp_rmem = 4096 4096 16777216" >> /etc/sysctl.confecho "net.ipv4.tcp_wmem = 4096 4096 16777216" >> /etc/sysctl.conf 其它沒有調整的參數,僅僅因為它們暫時對本次測試沒有帶來什么影響,實際環境中需要結合需要調整類似于SO_KEEPALIVE、tcpmax_orphans等大量參數。
本文代表一次實踐,不足之處,歡迎批評指正。
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的100万并发连接服务器笔记之1M并发连接目标达成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webform(八)——LinQ简单增、
- 下一篇: (计算机组成原理)第二章数据的表示和运算