以下是在/etc/sysctl.conf文件中配置的幾個重要內核參數,這幾個參數的設置關系到系統性能:
net.ipv4.tcp_syncookies
#此參數應該設置為1,防止SYN Flood。
處在SYN_RECV的TCP連接稱為半連接,存儲在SYN隊列。大量SYN_RECV會導致隊列溢出,后續請求將被內核直接丟棄,也就是SYN Flood攻擊。開啟syncookies后,當SYN隊列滿了后,TCP會通過原地址端口,目的地址端口和時間戳打造一個特別的Sequence Number(又叫cookie發回去,如果是攻擊者則不會有響應,如果是正常連接則把這個SYNCookie發回來,然后服務器端可以通過cookie建立連接(即使不在SYN隊列)。
net.ipv4.tcp_fin_timeout
#此參數默認值60,TCP保持在FIN_WAIT2狀態的時間,超時后直接處於CLOSED,所以降低tcp_fin_timeout有助於減少TIME_WAIT數量。注意:雖然shutdown(SHUD_WR)也會處於FIN_WAIT2狀態,但超時並不起作用。
net.ipv4.tcp_tw_recycle
#此參數默認值0,打開快速TIME_WAIT socket回收。
如果tcp_timestamps開啟的話,會緩存每個連接的最新時間戳,如果后續請求時間戳小於緩存的時間戳,即視為無效,相應的包被丟棄。所以如果是在NAT(Network Address Translation)網絡下,就可能出現數據包丟棄的現象,會導致大量的TCP連接建立錯誤。
net.ipv4.tcp_tw_resue
#此參數默認值0,是否重用TIME_WAIT狀態的socket用於新的連接。
這個選項要比net.ipv4.tcp_tw_recycle安全,從協議的角度看,復用是安全的。復用條件:
1)net.ipv4.tcp_timestamps選項必須打開(客戶端也必須打開) ;
2) 重用TIME_WAIT的條件是收到最后一個包后超過1秒;
net.ipv4.tcp_keepalive_time = 1200
#此參數表示TCP發送keepalive探測消息的間隔時間(秒), 用於確認TCP連接是否有效。當keepalive起用時,TCP發送keepalive消息的頻度。缺省是2小時,可改為20分鍾。
################################################################
###### Linux服務器產生大量CLOSE-WAIT的原因和處理方法 #####
################################################################
close_wait狀態出現的原因是被動關閉方未關閉socket造成
當客戶端因為某種原因先於服務端發出了FIN信號,就會導致服務端被動關閉,若服務端不主動關閉socket發FIN給Client,此時服務端Socket會處於CLOSE_WAIT狀態(而不是LAST_ACK狀態)。通常來說,一個CLOSE_WAIT會維持至少2個小時的時間(系統默認超時時間的是7200秒,也就是2小時)。如果服務端程序因某個原因導致系統造成一堆CLOSE_WAIT消耗資源,那么通常是等不到釋放那一刻,系統就已崩潰。
這里需要首先了解下tcp keepalive的三個參數:
默認tcp_keepalive_time 的值為7200 ,超時時間(開啟keepalive的閑置時長);
默認tcp_keepalive_intvl 的值為75 ,tcp檢查間隔時間(keepalive探測包的發送間隔);
默認tcp_keepalive_probes 的值為9 ,tcp檢查次數(如果對方不予應答,探測包的發送次數);
要根據自身的業務來調整這三個參數,有下面三種方式:
第一種方式: # vim /etc/sysctl.conf net.ipv4.tcp_keepalive_time = 1800 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl = 15 # sysctl -p 第二種方式: # echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time # echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl # echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes 第三種方式: # sysctl -w net.ipv4.tcp_keepalive_time=600 # sysctl -w net.ipv4.tcp_keepalive_probes=2 # sysctl -w net.ipv4.tcp_keepalive_intvl=2