Linux 單臺服務器上併發TCP鏈接數優化

問題:一臺服務器到底可以支持多少TCP併發鏈接呢?

1. 文件描述符限制:
    對於服務器來講,每個TCP鏈接都要佔用一個文件描述符,一旦文件描述符使用完,新的鏈接到來返回給咱們的錯誤是"Socket/File:Can't open so many files"      node

    這時,你須要明白操做系統能夠打開最大文件數的限制。

        進程限制(用戶限制):linux

  • 第一步,查看當前值
ulimit -n # 最大文件數,通常默認爲1024個
ulimit -u # 最大進程數,通常爲默認60000+

            執行 ulimit -n 輸出1024,說明對於一個進程而言最多隻能打開1024個文件,因此你要採用此默認配置最多也就能夠併發上千個TCP鏈接。

            臨時修改:ulimit -n 1000000,可是這種臨時修改只對當前登陸的用戶目前使用的環境有效,系統重啓或用戶退出會就失效。

            永久生效:修改/etc/security/limits.conf 文件:shell

# 修改文件數
                *    soft    nofile    1000000
                *    hard    nofile    1000000
                # 修改進程數 
                *    soft    noproc    60000 
                *    hard    noproc    60000 
  • 第二步,修改/etc/pam.d/login文件,在文件中添加以下行:

    session required /lib/security/pam_limits.sobash

    若是是64bit系統的話,應該爲 :
    session required /lib64/security/pam_limits.so服務器

  • 第三步,修改/etc/sysctl.conf文件,在文件中(清除文件原始內容)添加以下行(修改網絡內核對TCP鏈接的有關限制):
  • 設置Sysctl.conf用以提升Linux的性能 https://blog.csdn.net/21aspnet/article/details/6584792
net.ipv4.ip_local_port_range = 1024 65535
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn = 262144
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
  • 第四步,執行以下命令(使上述設置生效):  
/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1
  • 第五步,執行以下命令(linux系統優化完網絡必須調高系統容許打開的文件數才能支持大的併發,默認1024是遠遠不夠的):
 echo ulimit -HSn 1000000 >> /etc/rc.local
 echo ulimit -HSn 1000000 >>/root/.bash_profile
  ulimit -SHu 6000 >> /etc/rc.local
  ulimit -SHn 1000000 >> /etc/rc.local   

 

全侷限制:
            執行 cat /proc/sys/fs/file-nr  
                1216    0    187612
                (1) 1216:已經分配的文件描述符數
                (2) 0:已經分配但沒有使用的文件描述符數,這裏的意思是內核分配了1216,而後1216個都用光了,因此「分配了但沒有使用的 句柄數目」 爲 0 
                (3) 187612:最大文件句柄數
                注意:在kernel2.6 版本中第二項的值總爲0,這並非一個錯誤,它實際上意味着已經分配的文件描述符無一浪費的都已經
                被使用。

                能夠經過在/etc/sysctl.conf裏定義fs.file-max = 1000000 來調整最後一個值的大小

2. 端口號範圍限制:
    操做系統上端口號1024如下是系統保留的,從1024-65535是用戶使用的,因爲沒有tcp鏈接都要佔用一個端口號,因此咱們最多可使用
    60000多個併發鏈接,這是對客戶端的理解。
    分析一下:
        (1) 如何標識一個TCP鏈接? 系統用一個4元組來標識一個TCP鏈接:(local ip,local port,remote ip, remote port) 對於accept來講,accept的sock不佔新的端口 第一個local ip , local port 表明客戶端的ip地址和端口號。
        而咱們做爲服務器實際只是使用了bind這一個端口
        說明端口65535並非併發量的限制。
        (2) server最大tcp鏈接數:server一般固定在某一個本地端口上監聽,等待client的鏈接請求。不考慮地址重用的狀況下,即便多個ip
        本地監聽端口也是獨佔的。所以server端tcp鏈接4元組中只有remote ip 和 remote port 是可變的,所以最大tcp鏈接爲
        客戶端ip數 * 客戶端port數。 對於ipv4,不考慮ip地址等因素,最大tcp鏈接約爲2的32次方(ip數) * 2的16次方(port數)
        也就是  server端:單機最大tcp鏈接數約爲:2的48次方。


問題1:查看文件描述符使用 lsof查看到的句柄數和/proc/sys/fs/file-nr 值不同,爲何?cookie

[root@localhost ~]# lsof | wc -l
        710
        [root@localhost ~]# !cat
        cat /proc/sys/fs/file-nr
        416    0    1000000

    答案:一個文件能夠被多個進程打開,lsof所列出來的是每一個進程所打開的文件,因此lsof的數值比file-nr要大很正常。

問題2:關於文件句柄到底設置多大合適?

    查看句柄數的方法:網絡

[root@node1 ~]# cat /proc/sys/fs/file-nr
        832    0    97321        
        [root@node1 ~]# cat /proc/sys/fs/file-max
        97321        
        默認最大句柄數爲97321

        這個值在kernel的文檔裏意思是file-max通常爲內存大小(KB)的10%來計算,若是使用shell,能夠這樣計算:
        grep -r MemTotal /proc/meminfo | awk '{printf("%d",$2/10)}'  計算出來的值通常和默認最大句柄數近似。session

echo "fs.file-max = 100133" >> /etc/sysctl.conf && sysctl -p
相關文章
相關標籤/搜索