聚精會神分析如何提升TCP併發連接

聚精會神分析如何提升TCP併發連接

1、修改用戶進程可打開文件數限制

在Linux平臺上,無論編寫客戶端程序還是服務端程序,在進行高併發TCP連接處理時,最高的併發數量都要受到系統對用戶單一進程同時可打開文件數量的限制(這是因為系統為每個TCP連接都要創建一個socket句柄,每個socket句柄同時也是一個文件句柄)。可使用ulimit命令查看系統允許當前用戶單一進程打開的文件數限制:

ulimit -n

1024

這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的標準輸入,標準輸出,標準錯誤,服務器監聽 socket,進程間通訊的unix域socket等文件,那麼剩下的可用於客戶端socket連接的文件數就只有大概1024-10=1014個左右。也就是說缺省情況下,基於Linux的通訊程序最多允許同時1014個TCP併發連接。

對於想支持更高數量的TCP併發連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制是指Linux在當前系統能夠承受的範圍內進一步限制用戶同時打開的文件數;硬限制則是根據系統硬件資源狀況(主要是系統內存)計算出來的系統最多可同時打開的文件數量。通常軟限制小於或等於硬限制。

修改Linux系統對用戶的關於打開文件數的軟限制和硬限制:

修改/etc/security/limits.conf文件,在文件中添加如下行:

* soft nofile 102400

* hard nofile 102400

修改/etc/pam.d/login文件

session required /lib/security/pam_limits.so

pam_limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值

查看Linux系統級的最大打開文件數限制

cat /proc/sys/fs/file-max

6543106

這表明這臺Linux系統最多允許同時打開(即包含所有用戶打開文件數總和)12158個文件,是Linux系統級硬限制,所有用戶級的打開文件數限制都不應超過這個數值。

2.修改網絡內核對TCP連接的有關限制

在於Linux內核的TCP/IP協議實現模塊對系統中所有的客戶端TCP連接對應的本地端口號的範圍進行了限制(例如,內核限制本地端口號的範圍為1024~32768之間)。當系統中某一時刻同時存在太多的TCP客戶端連接時,由於每個TCP客戶端連接都要佔用一個唯一的本地端口號(此端口號在系統的本地端口號範圍限制中),如果現有的TCP客戶端連接已將所有的本地端口號佔滿,則此時就無法為新的TCP客戶端連接分配一個本地端口號了,因此係統會在這種情況下在connect()調用中返回失敗,並將錯誤提示消息設為“Can't assignrequested address”。

修改/etc/sysctl.conf文件,在文件中添加如下行:

net.ipv4.ip_local_port_range = 1024 65000

sysctl -p 執行立即生效

這表明將系統對本地端口範圍限制設置為1024~65000之間。請注意,本地端口範圍的最小值必須大於或等於1024;而端口範圍的最大值則應小於或等於65535。

net.ipv4.ip_conntrack_max = 10240

這表明將系統對最大跟蹤的TCP連接數限制設置為10240。請注意,此限制值要儘量小,以節省對內核內存的佔用。則理論上單獨一個進程最多可以同時建立10000多個TCP客戶端連接。

3.使用支持高併發網絡I/O的編程技術

在開發支持高併發TCP連接的Linux應用程序時,應儘量使用epoll或AIO技術來實現併發的TCP連接上的I/O控制,這將為提升程序對高併發TCP連接的支持提供有效的I/O保證。

排查tcp連接數問題常用命令:

#查看tcp連接數狀態

netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

#查看所有監聽端口

netstat -lntp

#查看那些ip連接數較多

netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -r

#接收的TCP包數

RxTcpNum=`netstat -s | grep -E 'segments received' | head -1 | awk '{print $1}'`

echo -e "TCP Received:" $RxTcpNum

#發送TCP包數

SendTcpNum=`netstat -s | grep -E 'segments send out' | head -1 | awk '{print $1}'`

echo -e "TCP Send Out:" $SendTcpNum

#失敗的TCP包數

BadTcpNum=`netstat -s | grep -E 'bad segments received' | head -1 | awk '{print $1}'`

echo -e "Tcp Bad Package:" $BadTcpNum

#TCP重傳率

Retransmited=`netstat -s | grep -E 'segments retransmited' | head -1 | awk '{print $1}'`

ReSendRatio=`

echo "$Retransmited $SendTcpNum" | awk '{printf("%.2f",$1/$2*100)}'`

echo -e "Tcp Retransmission Ratio:" $ReSendRatio

#TCP活躍數

ActiveOpenNum=`netstat -s | grep -E 'active connections openings' | head -1 | awk '{print $1}'`

echo -e "TCP Active Open:" $ActiveOpenNum

狀態描述:

CLOSED:無連接是活動的或正在進行

LISTEN:服務器在等待進入呼叫

SYN_RECV:一個連接請求已經到達,等待確認

SYN_SENT:應用已經開始,打開一個連接

ESTABLISHED:正常數據傳輸狀態

FIN_WAIT1:應用說它已經完成

FIN_WAIT2:另一邊已同意釋放

ITMED_WAIT:等待所有分組死掉

CLOSING:兩邊同時嘗試關閉

TIME_WAIT:另一邊已初始化一個釋放,表示正在佔用端口

LAST_ACK:等待所有分組死掉

相關推薦

推薦中...