高並發的影響因素除了硬件,Web服務器外,操作系統對TCP相關參數的配置也會對其有很大影響。
默認情況下Linux內核參數是考慮通用場景的(如ulimits -n 限定為1024),這在高並發訪問的Web服務器下會造成影響。所以一般需要進行內核參數的調整,來使Web服務器(如Nginx)可以支持更高的並發。
有了以上說明,我們來看如何修改以及需要修改哪些參數。
修改方式有sysctl命令及sysctl.conf兩種:
1、 sysctl -a查看所有內核參數 , sysctl -w 參數名=值 動態寫入內核參數
2、vi /etc/sysctl.conf文件就可以修改內核參數,sysctl -p 使內核參數生效
那么一般哪些參數需要修改呢:
- fs.file-max=1024 這個參數表示一個進程可以同時打開的最大文件句柄數,對應於ulimits -n的設置。我們知道Linux下一切皆文件。那么建立一個TCP連接其實對應的也是一個sock文件。該值過小,將極大影響並發連接數。默認應該是1024
- net.ipv4.tcp_tw_reuse=1 這個參數表示是否允許將TIME_WAIT狀態的socket重新用於新的TCP連接,這對某種場景下用於客戶端的服務器也是很有意義的。
- net.ipv4.tcp_keepalive_time = 1200 這個參數表示TCP發送keepalive保活心跳的頻率(注意與HTTP keepalive區分),設置小一點,可以更快地清理無效的連接,以避免資源浪費。
- net.ipv4.tcp_max_tw_buckets =18000 表示允許處於TIME_WAIT套接字數量的最大值,默認18000。可以根據情況適當調小點,以避免資源浪費。
- net.ipv4.tcp_max_syn_backlog = 128。TCP半連接隊列的最大長度。該值是可以調大以避免Nginx來不及accept的新連接不至於被內核丟棄。
(linux有2個隊列,一個就是在握手過程中的隊列(半連接,第二次握手至第三次握手期間),而另一個就是握手成功的隊列(完全連接,三次握手成功后,服務端程序accept之前)
過程如下:收到客戶端的syn請求 ->將這個請求放入syn_table中去->服務器端回復syn-ack->收到客戶端的ack->放入accept queue中。) - net.core.somaxconn = 128 每一個端口最大的監聽隊列的長度(完全連接)。這個就是平常編碼時listen(port,backlog)中的backlog的上限值。
其他的參數調整主要是緩存方面的,如:net.ipv4.tcp_rmem,wmem。
詳見內核文檔:[https://github.com/torvalds/linux/blob/a72db42cee37a43f8a40e1f47358ac86921ad8e4/Documentation/networking/ip-sysctl.txt]