歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> GNU Linux高並發性能優化方案

GNU Linux高並發性能優化方案

日期:2017/2/28 14:00:13   编辑:Linux教程

/***********************************************************
* 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系統中,影響連接個數的因素主是由於單個進程能夠打開的最大文件數、端口數量決定的;而一個基於tcp的服務器的並發,除了上文說過的兩個因素外,還有因為主要的tcp連接的很多屬性,而問題最大的則是連接斷開後的連接會在TIME_WAIT狀態一直存在60秒,這就造成了在大量高並發的情況下當連接為此TIME_WAIT狀態時沒有可用連接。

1、修改端口號范圍:
默認范圍:

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

眾所周知,端口號的范圍為0~65535,知名端口號介於1~255之間,256~1023之間的端口號通常都是由系統占用,所以我們需要更多可以使用的端口號的話,那麼就需要修改系統中對端口使用范圍變量;

修改方法:
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

若端口不夠用的時候報錯信息
若沒有空閒的端口可以使用時,將會報錯,如:
connect() to ip:80 failed (99: Cannot assign requested address)

注意:
修改了端口的范圍後,若是有多個服務在一台設備上時,若是先被其它服務先行啟動將另外的服務的“眾所周知”的端口給占用了,那麼這個問題就比較不太好處理,在這種情況下,對於需要監聽的服務進行先行啟動,將服務要使用的“眾所周知”的端口先行占用,就不會發生比較麻煩的情況了。

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的後續請求的時間戳小於緩存中的時間戳,內核就會丟棄該請求。

什麼樣的場景會使時間戳會小於緩存中的時間戳呢?
類似的故障場景:
多個客戶端通過一個NAT訪問一台服務器,因為NAT只改IP地址信息,但不會改變timestamp(TCP的時間戳不是系統時間,而是系統啟動的時間uptime,所以兩台機器的的TCP時間戳一致的可能性很小),那麼就會出現請求被丟棄的情況,所以很容易造成連接失敗的情況。
服務器上開啟了tcp_tw_recycle用於TIME_WAIT的快速回收故障現象和分析步驟:
1) 通過NAT出口的多個客戶端經常請求Web服務器無響應;
2) 在服務器抓包,發現服務端可以收到客戶端的SYN請求,但是沒有回應SYN,ACK,也就是說內核直接將包丟棄了。

解決方法:
1) 關閉服務其端的tcp_timestamps,故障可以解決,但是這麼做存在安全和性能隱患,強烈建議不關閉此變量;
2) 關閉tcp_tw_recycle,故障也可以解決。推薦NAT環境下的機器不要開啟該選項;
3)調整網絡拓撲避免NAT的這種類似的情況;
4)客戶端使用同一個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等服務器,上幾行的參數可以很好地減少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數量的限制,若服務器過載可以增大此值;
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

Copyright © Linux教程網 All Rights Reserved