netstat
netstat
命令是 linux 下一個很是有用的命令,顧名思義,其做用是查詢當前的網絡狀態。
以最經常使用的查詢 TCP 鏈接狀態爲例,在 Shell 裏運行如下命令:linux
netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c
你會看到當前全部 TCP 鏈接的狀態計數:程序員
有更高追求的程序員,可能會想吧結果美化一下。好比,使用下面的命令:vim
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
你會獲得以下的結果:服務器
上述兩個命令的結果不一樣,是由於我運行命令的時機不一樣,他們的意義是同樣的,僅僅只有格式的區別。cookie
這些狀態有什麼含義呢?咱們首先看一下 TCP 狀態轉換圖:網絡
TCP 狀態轉換圖併發
總結各狀態大體意義以下:socket
CLOSED
初始狀態。
LISTEN
服務端處於監聽狀態,能夠接受鏈接。
SYN_SENT
客戶端鏈接併發送 SYN 報文,進入 SYN_SENT
狀態,等待服務端確認。
SYN_RCVD
服務端接受到了 SYN 報文,當收到客戶端的 ACK 報文後,會進入到 ESTABLISHED
狀態。
ESTABLISHED
鏈接已經創建,進入數據傳輸狀態。
FIN_WAIT_1
創建鏈接後,其中一方請求終止鏈接,等待對方的 FIN 報文。
FIN_WAIT_2
半鏈接,有一方要求關閉鏈接,但另外還告訴對方,我還有數據須要傳輸,稍後再關閉鏈接。
TIME_WAIT
收到了對方的 FIN 報文,併發送出了 ACK 報文,2MSL 後便可回到 CLOSED
可用狀態。
CLOSE_WAIT
等待關閉。
CLOSING
當發送 FIN 報文後,並未收到對方的 ACK 報文,卻收到了 FIN 報文,表示雙方都正在關閉鏈接。
LAST_ACK
被動關閉一方在發送 FIN 報文後,最後等待對方的 ACK 報文。tcp
其中 SYN_RECV
、ESTABLISHED
、TIME_WAIT
是對咱們比較有意義的幾個狀態。優化
SYN_RECV
表示正在等待處理的請求數。SYN_RECV
過多或居高不下,能夠理解爲服務器並不能及時處理全部的請求。這時要考慮進行效率優化,或增長更多的服務器;
ESTABLISHED
表示正在進行數據傳輸的請求數。一般與在線人數和併發相關,能夠做爲服務器負載能力的一項指標。
TIME_WAIT
表示處理完畢,等待超時結束的請求數。若 TIME_WAIT
過多,可調整內核參數進行優化,若仍無效,則需注意是否遭到了惡意攻擊。如有大量的 SYN_RECEIVED
、TIME_WAIT
、FIN_WAIT_1
等狀態存在,而 ESTABLISHED
不多,則可初步判斷存在 DDOS 攻擊。
TIME_WAIT
主動關閉的一方在發送最後一個 ACK 報文後,就會進入 TIME_WAIT
狀態,停留 2MSL(max segment lifetime)。
TCP/IP 協議中如此設計,主要有兩個緣由:
防止上一次鏈接中的包,迷路後從新出現,影響新鏈接。 通過 2MSL,上一次鏈接中全部的重複包都會消失。
可靠的關閉 TCP 鏈接。 主動關閉方發送的最後一個 ACK(FIN) 報文,有可能丟失,這時被動方會從新發送 FIN 報文, 若是這時主動方處於
CLOSED
狀態 ,就會響應 RST 報文而不是 ACK 報文。因此主動方要處於TIME_WAIT
狀態,而不能是CLOSED
。
TIME_WAIT
並不會佔用太多資源,除非受到惡意攻擊。
TIME_WAIT
經過調整內核參數,能夠緩解 TIME_WAIT
過多的狀況。
首先打開配置文件 vim /etc/sysctl.conf
,修改如下配置:
# 表示開啓 SYN cookies。當出現 SYN 等待隊列溢出時,啓用 cookies 來處理,可防範少許 SYN 攻擊,默認爲 0,表示關閉; net.ipv4.tcp_syncookies = 1 # 表示開啓重用。容許將 TIME-WAIT sockets 從新用於新的 TCP 鏈接,默認爲 0,表示關閉; net.ipv4.tcp_tw_reuse = 1 # 表示開啓 TCP 鏈接中 TIME-WAIT sockets 的快速回收,默認爲 0,表示關閉; net.ipv4.tcp_tw_recycle = 1 # 修改系統默認的 TIMEOUT 時間 net.ipv4.tcp_fin_timeout = 1
而後執行以命令 /sbin/sysctl -p
讓參數生效。