因為在做爬蟲分散式系統的過程中,涉及到了一些linux系統優化方面的知識,所以來總結一下,我們會對linux的不同模塊做相關的基本優化,這篇文章主要講述的是關於tcp協議棧的參數優化。

1.機器環境

Linux EOS01 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.4 (Final)

2.具體實施

2.1 由於每台機器的文件描述符都是處於默認的1024的標準值,對於高並發的系統來說,很容易達到瓶頸,因此我們需要重定文件描述符數量,可以採用ansible對各個伺服器批量設置。

vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535

2.2 關於我們對於系統tcp協議棧的參數設置

vi /etc/sysctl.conf
net.ipv4.tcp_fin_timeout=10

net.ipv4.tcp_syncookies=1

#開啟重用。允許將TIME-WAIT sockets 重新用於新的TCP 連接
net.ipv4.tcp_tw_reuse=1

#啟用timewait 快速回收
net.ipv4.tcp_tw_recycle=1

net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_max_syn_backlog=8192
net.ipv4.tcp_max_tw_buckets=5000

net.ipv4.tcp_timestamps = 0

#每300秒 探測一次tcp連接是否空閑,一共探測2次,每次間隔15秒
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 2

net.ipv4.tcp_keepalive_time = 300

然後執行 /sbin/sysctl -p 讓參數生效

具體的參數含義可以參考如下:

1. fs.file-max

最大可以打開的文件描述符數量,注意是整個系統。

在伺服器中,我們知道每創建一個連接,系統就會打開一個文件描述符,所以,文件描述符打開的最大數量也決定了我們的最大連接數

select在高並發情況下被取代的原因也是文件描述符打開的最大值,雖然它可以修改但一般不建議這麼做,詳情可見unp select部分。

2.net.ipv4.tcp_max_syn_backlog

Tcp syn隊列的最大長度,在進行系統調用connect時會發生Tcp的三次握手,server內核會為Tcp維護兩個隊列,Syn隊列和Accept隊列,Syn隊列是指存放完成第一次握手的連接,Accept隊列是存放完成整個Tcp三次握手的連接,修改net.ipv4.tcp_max_syn_backlog使之增大可以接受更多的網路連接。

注意此參數過大可能遭遇到Syn flood攻擊,即對方發送多個Syn報文端填充滿Syn隊列,使server無法繼續接受其他連接

可參考此文tech.uc.cn/?

我們看下 man 手冊上是如何說的:

The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for com‐ pletely established sockets waiting to be accepted, instead of the number of incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical maximum length and this setting is ignored. See tcp(7) for more information. If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is 128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.

自 Linux 內核 2.2 版本以後,backlog 為已完成連接隊列的最大值,未完成連接隊列大小以 /proc/sys/net/ipv4/tcp_max_syn_backlog 確定,但是已連接隊列大小受 SOMAXCONN 限制,為 min(backlog, SOMAXCONN)

3.net.ipv4.tcp_syncookies

修改此參數可以有效的防範上面所說的syn flood攻擊

原理:在Tcp伺服器收到Tcp Syn包並返回Tcp Syn+ack包時,不專門分配一個數據區,而是根據這個Syn包計算出一個cookie值。在收到Tcp ack包時,Tcp伺服器在根據那個cookie值檢查這個Tcp ack包的合法性。如果合法,再分配專門的數據區進行處理未來的TCP連接。

默認為0,1表示開啟

4.net.ipv4.tcp_keepalive_time

Tcp keepalive心跳包機制,用於檢測連接是否已斷開,我們可以修改默認時間來間斷心跳包發送的頻率。

keepalive一般是伺服器對客戶端進行發送查看客戶端是否在線,因為伺服器為客戶端分配一定的資源,但是Tcp 的keepalive機制很有爭議,因為它們可耗費一定的帶寬。

Tcp keepalive詳情見Tcp/ip詳解卷1 第23章

5.net.ipv4.tcp_tw_reuse

我的上一篇文章中寫到了time_wait狀態,大量處於time_wait狀態是很浪費資源的,它們佔用server的描述符等。

修改此參數,允許重用處於time_wait的socket。

默認為0,1表示開啟

6.net.ipv4.tcp_tw_recycle

也是針對time_wait狀態的,該參數表示快速回收處於time_wait的socket。

默認為0,1表示開啟

7.net.ipv4.tcp_fin_timeout

修改time_wait狀的存在時間,默認的2MSL

注意:time_wait存在且生存時間為2MSL是有原因的,見我上一篇博客為什麼會有time_wait狀態的存在,所以修改它有一定的風險,還是根據具體的情況來分析。

8.net.ipv4.tcp_max_tw_buckets

所允許存在time_wait狀態的最大數值,超過則立刻被清楚並且警告。

9.net.ipv4.ip_local_port_range

表示對外連接的埠範圍。

10.somaxconn

前面說了Syn隊列的最大長度限制,somaxconn參數決定Accept隊列長度,在listen函數調用時backlog參數即決定Accept隊列的長度,該參數太小也會限制最大並發連接數,因為同一時間完成3次握手的連接數量太小,server處理連接速度也就越慢。伺服器端調用accept函數實際上就是從已連接Accept隊列中取走完成三次握手的連接。

Accept隊列和Syn隊列是listen函數完成創建維護的。

/proc/sys/net/core/somaxconn修改

3. 參考資料

blog.csdn.net/Lixuanshe


推薦閱讀:
相关文章