在服務端,連接配接達到一定數量,諸如50W時,有些隐藏很深的問題,就不斷的抛出來。 通過檢視dmesg指令檢視,發現大量TCP: too many of orphaned sockets錯誤,也很正常,下面到了需要調整tcp socket參數的時候了。
第一個需要調整的是tcp_rmem,即TCP讀取緩沖區,機關為位元組,檢視預設值
預設值為87380 byte ≈ 86K,最小為4096 byte=4K,最大值為4064K。
第二個需要調整的是tcp_wmem,發送緩沖區,機關是位元組,預設值
解釋同上
第三個需要調整的tcp_mem,調整TCP的記憶體大小,其機關是頁,1頁等于4096位元組。系統預設值:
tcp_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調整語句為:
備注: 為了節省記憶體,設定tcp讀、寫緩沖區都為4K大小,<code>tcp_mem</code>三個值分别為3G 8G 16G,<code>tcp_rmem</code>和<code>tcp_wmem</code>最大值也是16G。
經過若幹次的嘗試,最終達到目标,1024000個持久連接配接。1024000數字是怎麼得來的呢,兩台實體機器各自發出64000個請求,兩個配置為6G左右的centos測試端機器(綁定7個橋接或NAT連接配接)各自發出640007 = 448000。也就是 1024000 = (64000) + (64000) + (640007) + (64000*7), 共使用了16個網卡(實體網卡+虛拟網卡)。
終端輸出
線上使用者目标達到1024000個!
服務啟動時記憶體占用:
<code> total used free shared buffers cached Mem: 10442 271 10171 0 22 78 -/+ buffers/cache: 171 10271 Swap: 8127 0 8127</code>
<code></code>
系統達到1024000個連接配接後的記憶體情況(執行三次 free -m 指令,擷取三次結果):
<code> total used free shared buffers cached Mem: 10442 7781 2661 0 22 78 -/+ buffers/cache: 7680 2762 Swap: 8127 0 8127 total used free shared buffers cached Mem: 10442 7793 2649 0 22 78 -/+ buffers/cache: 7692 2750 Swap: 8127 0 8127 total used free shared buffers cached Mem: 10442 7804 2638 0 22 79 -/+ buffers/cache: 7702 2740 Swap: 8127 0 8127</code>
這三次記憶體使用分别是7680,7692,7702,這次不取平均值,取一個中等偏上的值,定為7701M。那麼程式接收1024000個連接配接,共消耗了 7701M-171M = 7530M記憶體, 7530M*1024K / 1024000 = 7.53K, 每一個連接配接消耗記憶體在為7.5K左右,這和在連接配接達到512000時所計算較為吻合。
虛拟機運作Centos記憶體占用,不太穩定,但一般相差不大,以上數值,僅供參考。
執行top -p 某刻輸出資訊:
<code> Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie Cpu(s): 0.2%us, 6.3%sy, 0.0%ni, 80.2%id, 0.0%wa, 4.5%hi, 8.8%si, 0.0%st Mem: 10693580k total, 6479980k used, 4213600k free, 22916k buffers Swap: 8323056k total, 0k used, 8323056k free, 80360k cached PID 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 </code>
執行vmstate:
擷取目前socket連接配接狀态統計資訊:
擷取目前系統打開的檔案句柄:
此時任何類似于下面查詢操作都是一個慢,等待若幹時間還不見得執行完畢。
以上兩個指令在二三十分鐘過去了,還未執行完畢,隻好停止。
本次從頭到尾的測試,所需要有的linux系統需要調整的參數也就是那麼幾個,彙總一下:
<code> echo "* - nofile 1048576" >> /etc/security/limits.conf echo "fs.file-max = 1048576" >> /etc/sysctl.conf echo "net.ipv4.ip_local_port_range = 1024 65535" >> /etc/sysctl.conf 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</code>
其它沒有調整的參數,僅僅因為它們暫時對本次測試沒有帶來什麼影響,實際環境中需要結合需要調整類似于SO_KEEPALIVE、tcpmax_orphans等大量參數。
本文轉自 憬薇 51CTO部落格,原文連結:http://blog.51cto.com/welcomeweb/1975364