一臺Linux伺服器可以負載多少個連線?
首先我們來看如何標識一個TCP連線?系統是通過一個四元組來識別,(src_ip,src_port,dst_ip,dst_port)即源IP、源埠、目標IP、目標埠。比如我們有一臺服務192.168.0.1,開啟埠80.那麼所有的客戶端都會連線到這臺服務的80埠上面。有一種誤解,就是我們常說一臺機器有65536個埠,那麼承載的連線數就是65536個,這個說法是極其錯誤的,這就混淆了源埠和訪問目標埠。我們做壓測的時候,利用壓測客戶端,這個客戶端的連線數是受到埠數的限制,但是伺服器上面的連線數可以達到成千上萬個,一般可以達到百萬(4C8G配置),至於上限是多少,需要看優化的程度。具體做法如下:
我們在壓測一臺目標伺服器,想看下負載的連線數,當我們壓到一定數量的時候,控制檯突然報"too many open files",這是因為linux系統建立一個TCP連線的時候,都會建立一個socket控制代碼,每個socket控制代碼就是一個檔案控制代碼。作業系統對開啟的檔案控制代碼數量是有限制的。Unix/Linux 基本哲學之一就是 "一切皆檔案",要提高TCP承載量,就需要調整檔案控制代碼。
第一步:修改檔案控制代碼數量限制
# 檢視當前使用者允許TCP開啟的檔案控制代碼最大數
ulimit -n
# 修改檔案控制代碼
vim /etc/security/limits.conf
* soft nofile 655350
* hard nofile 655350
修改後,退出終端視窗,重新登入(不需要重啟伺服器),就能看到最新的結果了。這是優化的第一步,修改檔案控制代碼限制。
注意: soft nofile (軟限制)是指Linux在當前系統能夠承受的範圍內進一步限制使用者同時開啟的檔案數 hard nofile (硬限制)是根據系統硬體資源狀況(主要是系統記憶體)計算出來的系統最多可同時開啟的檔案數量 通常軟限制小於或等於硬限制
第二步:TCP引數調優
引數 | 預設配置 | 調整配置 | 說明 |
---|---|---|---|
fs.file-max | 1048576 | 9999999 | 所有程序開啟的檔案描述符數 |
fs.nr_open | 1635590 | 1635590 | 單個程序可分配的最大檔案數 |
net.core.rmem_default | 124928 | 262144 | 預設的TCP讀取緩衝區 |
net.core.wmem_default | 124928 | 262144 | 預設的TCP傳送緩衝區 |
net.core.rmem_max | 124928 | 8388608 | 預設的TCP最大讀取緩衝區 |
net.core.wmem_max | 124928 | 8388608 | 預設的TCP最大(max)傳送緩衝區 |
net.ipv4.tcp_wmem | 4096 16384 4194304 | 4096 16384 8388608 | TCP傳送緩衝區 |
net.ipv4.tcp_rmem | 4096 87380 4194304 | 4096 87380 8388608 | TCP讀取緩衝區 |
net.ipv4.tcp_mem | 384657 512877 769314 | 384657 512877 3057792 | TCP記憶體大小 |
net.core.netdev_max_backlog | 1000 | 5000 | 在每個網路介面接收資料包的速率比核心處理這些包的速率快時,允許送到佇列的資料包的最大數目 |
net.core.optmem_max | 20480 | 81920 | 每個套接字所允許的最大緩衝區的大小 |
net.core.somaxconn | 128 | 2048 | 每一個埠最大的監聽佇列的長度,這是個全域性的引數 |
net.ipv4.tcp_fin_timeout | 60 | 30 | 對於本端斷開的socket連線,TCP保持在FIN-WAIT-2狀態的時間(秒)。對方可能會斷開連線或一直不結束連線或不可預料的程序死亡 |
net.core.netdev_max_backlog | 1000 | 10000 | 在每個網路介面接收資料包的速率比核心處理這些包的速率快時,允許送到佇列的資料包的最大數目 |
net.ipv4.tcp_max_syn_backlog | 1024 | 2048 | 對於還未獲得對方確認的連線請求,可儲存在佇列中的最大數目。如果伺服器經常出現過載,可以嘗試增加這個數字 |
net.ipv4.tcp_max_tw_buckets | 5000 | 5000 | 系統在同時所處理的最大timewait sockets數目 |
net.ipv4.tcp_tw_reuse | 0 | 1 | 是否允許將TIME-WAIT sockets重新用於新的TCP連線 |
net.ipv4.tcp_keepalive_time | 7200 | 900 | 表示TCP連結在多少秒之後沒有資料報文傳輸時啟動探測報文(傳送空的報文) |
net.ipv4.tcp_keepalive_intvl | 75 | 30 | 表示前一個探測報文和後一個探測報文之間的時間間隔 |
net.ipv4.tcp_keepalive_probes | 9 | 3 | 表示探測的次數 |
從上面的配置引數中我們可以知道,在Linux核心中為tcp傳送和接收都做了緩衝佇列,這樣可以提高系統的吞吐量。 以上這些引數都是在 /etc/sysctl.conf 檔案中定義的,有的引數在檔案中可能沒有定義,系統給定了預設值,需要修改的話,直接在檔案中新增或修改,然後執行sysctl -p命令讓其生效。
注意: 引數值並不是設定的越大越好,有的需要考慮伺服器的硬體配置,引數對伺服器上其它服務的影