1. 程式人生 > >GNU Linux高並發性能優化方案

GNU Linux高並發性能優化方案

.html 要求 得到 oca 大數 bucket ams his syn

/***********************************************************
* Author : Samson
* Date : 07/14/2015
* Test platform:
* gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
* GNU bash, 4.3.11(1)-release (x86_64-pc-linux-gnu)
* Nginx version:
* Nginx 1.6.2
* Nginx 1.8.0
* *********************************************************

/

GNU Linux高並發性能優化方案

在GNU Linux系統中,影響連接個數的因素主是由於單個進程能夠打開的最大文件數、port數量決定的;而一個基於tcp的server的並發,除了上文說過的兩個因素外,還有由於基本的tcp連接的非常多屬性,而問題最大的則是連接斷開後的連接會在TIME_WAIT狀態一直存在60秒,這就造成了在大量高並發的情況下當連接為此TIME_WAIT狀態時沒有可用連接。

1、改動port號範圍:

默認範圍:

cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000

眾所周知,port號的範圍為0~65535,知名port號介於1~255之間。256~1023之間的port號通常都是由系統占用,所以我們須要很多其他能夠使用的port號的話,那麽就須要改動系統中對port使用範圍變量;

改動方法:

1)、echo “1024 65535” > /proc/sys/net/ipv4/ip_local_port_range

2)、在/etc/sysctl.conf中進行例如以下的設置:

net.ipv4.ip_local_port_range=1024 65535
然後運行: sysctl -p 對這些設置進行生效;

3)、直接使用命令進行系統變量的優化

sysctl -w net.ipv4.ip_local_port_range=1024 65535

若port不夠用的時候報錯信息

若沒有空暇的port能夠使用時。將會報錯。如:
connect() to ip:80 failed (99: Cannot assign requested address)

註意:

改動了port的範圍後。若是有多個服務在一臺設備上時。若是先被其他服務先行啟動將另外的服務的“眾所周知”的port給占用了,那麽這個問題就比較不太優點理,在這種情況下,對於須要監聽的服務進行先行啟動,將服務要使用的“眾所周知”的port先行占用。就不會發生比較麻煩的情況了。

2、改動系統全部進程能夠打開的文件數:

cat /proc/sys/fs/file-max
203466

若要改動的話:
echo 403466 > /proc/sys/fs/file-max

3、對於處理TIME_WAIT的問題,通過設置下面兩項能夠極大地提高並發

在進行了通信完畢後,完畢通信的連接差點兒相同在秒級間就進行了回收,經測試,再使用netstat -ntp,都不會再看到剛才使用的連接,可是在官方文檔中說明了(Default value is 0. It should not be changed without advice/request of technical experts.)使用這兩種方式須要非常慎重;例如以下(改動方法請參看上面的改動方式):
net.ipv4.tcp_tw_reuse = 1

//表示開啟重用。同意將TIME-WAIT sockets又一次用於新的TCP連接,默覺得0,表示關閉;
net.ipv4.tcp_tw_recycle = 1
//表示開啟TCP連接中TIME-WAIT sockets的高速回收,默覺得0,表示關閉。

由於以上兩項在官方文檔中有這種描寫敘述”It should not be changed without advice/request of technical experts.“,也即是說,這兩項在某些情況下會產生負作用或影響。

可能出現的影響:

net.ipv4.tcp_tw_recycle是與net.ipv4.tcp_timestamps是密切相關的,而net.ipv4.tcp_timestamps默認是開啟的,當tcp_tw_recycle和tcp_timestamps同一時候打開時會激活TCP的一種隱藏屬性:緩存連接的時間戳。

60秒內,同一源IP的興許請求的時間戳小於緩存中的時間戳,內核就會丟棄該請求。

什麽樣的場景會使時間戳會小於緩存中的時間戳呢?

相似的故障場景:
多個client通過一個NAT訪問一臺server,由於NAT僅僅改IP地址信息,但不會改變timestamp(TCP的時間戳不是系統時間。而是系統啟動的時間uptime。所以兩臺機器的的TCP時間戳一致的可能性非常小)。那麽就會出現請求被丟棄的情況,所以非常easy造成連接失敗的情況。


server上開啟了tcp_tw_recycle用於TIME_WAIT的高速回收故障現象和分析步驟:
1) 通過NAT出口的多個client常常請求Webserver無響應;
2) 在server抓包,發現服務端能夠收到client的SYN請求。可是沒有回應SYN,ACK,也就是說內核直接將包丟棄了。

解決方法:

1) 關閉服務其端的tcp_timestamps。故障能夠解決,可是這麽做存在安全和性能隱患。強烈建議不關閉此變量;
2) 關閉tcp_tw_recycle,故障也能夠解決。推薦NAT環境下的機器不要開啟該選項;
3)調整網絡拓撲避免NAT的這種相似的情況。
4)client使用同一個NTP服務進行時間同步。使時間同步避免timestamp差異;

其他優化參數

net.ipv4.tcp_fin_timeout = 30
//表示假設套接字由本端要求關閉。這個參數決定了它保持在FIN-WAIT-2狀態的時間。
net.ipv4.tcp_keepalive_time = 1200
//表示當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改為20分鐘。
net.ipv4.tcp_max_tw_buckets = 5000
//表示系統同一時候保持TIME_WAIT套接字的最大數量,假設超過這個數字,
//TIME_WAIT套接字將立馬被清除並打印警告信息。默覺得180000,改為5000。


//對於Apache、Nginx等server,上幾行的參數能夠非常好地降低TIME_WAIT套接字數量。

//此值和/proc/sys/net/ipv4/tcp_max_syn_backlog是一樣的,也是對listen()函數中的backlog參數的限制,依照文檔中的說明,應該最好是設置成和/proc/sys/net/ipv4/tcp_max_syn_backlog一樣的值,此值的默認值是128:
cat /proc/sys/net/core/somaxconn
128
net.core.somaxconn = 40000

//指定未完畢連接隊列的最大長度,默覺得1024個,是對socket的listen()函數中的backlog數量的限制,若server過載能夠增大此值;
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024
net.ipv4.tcp_max_syn_backlog = 40000

4、調整每一個進程最大打開文件描寫敘述符限制

調整文件描寫敘述符限制:

$ ulimit -n
1024
改動此值。ulimit -n 4096

$vi /etc/security/limits.conf
//Setting Shell Limits for File Descriptors
*soft nofile 8192
*hard nofile 8192

這二者的差別,在/etc/security/limits.conf配置文件裏配置好後,進行重新啟動後再次使用ulimit -n將得到的值是8192.

5、通過又一次編譯內核代碼降低TCP連接的TIME-WAIT時間

在內核代碼中的include/net/tcp.h文件裏。TIME-WAIT的定義例如以下:
//#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
* state, about 60 seconds */
能夠通過改動TCP_TIMEWAIT_LEN的值。來加快連接的釋放;改動後,內核進行編譯後進行替換。

Nginx的配置與系統環境變量間的關系

系統默認的是1024。若在Nginx的配置文件裏,配置了worker_connections 4096;後,再啟動時,會出現這種一個警告:

nginx: [warn] 4096 worker_connections exceed open file resource limit: 1024
Nginx中的這些和系統變量有關的,是依據系統中的配置而進行設置的。若大於了系統變量的範圍的話,不會生效,會被默認成系統的值,如每一個worker進行能夠打開的文件數量就被默認成系統的值1024;

註意:

改動內核變量是有風險的,最好是在測試環境進行測試通過。再將配置平移到生產環境。

REF:

IPV4和IPV6的內核參數各項的意義及取值:
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
關於/proc文件夾下的主要項的介紹:
http://man7.org/linux/man-pages/man5/proc.5.html

GNU Linux高並發性能優化方案