解決TIME WAIT狀態常見的解決辦法

2021-07-12 04:28:33 字數 3015 閱讀 8583

time_wait狀態:

伺服器中保持大量的time_wait是很不好的事情,它可能會導致伺服器暫時處理不了新的鏈結,作業系統中提供的檔案描述符是在一定數量的,多出來的請求連線,是無法分配的。

在linux下使用下面的命令可以檢視當時系統中所維持的tcp狀態資訊。

netstat -n | awk '/^tcp/  end ' 

如何避免time_wait所占用的大量時間?

方式一c庫中提供了乙個對tcp鏈結很有用的函式。

int setsockopt(int sockfd, int level, int optname,

const void *optval, socklen_t optlen);

sockfd表示乙個socket描述字。

level:選項定義的層次;支援sol_socket、ipproto_tcp、ipproto_ip和ipproto_ipv6。

optname:需設定的選項。

optval:指標,指向存放選項待設定的新值的緩衝區。

optlen:optval緩衝區長度。

setsockopt()支援下列選項。其中「型別」表明optval所指資料的型別。

選項      型別 意義

so_broadcast bool 允許套介面傳送廣播資訊。

so_debug   bool 記錄除錯資訊。

so_dontliner bool 不要因為資料未傳送就阻塞關閉操作。設定本選項相當於將so_linger的l_onoff元素置為零。

so_dontroute bool 禁止選徑;直接傳送。

so_keepalive bool 傳送「保持活動」包。

so_linger struct linger far* 如關閉時有未傳送資料,則逗留。

so_oobinline bool 在常規資料流中接收帶外資料。

so_rcvbuf int 為接收確定緩衝區大小。

so_reuseaddr bool 允許套介面和乙個已在使用中的位址**。

so_sndbuf int 指定傳送緩衝區大小。

tcp_nodelay bool 禁止傳送合併的nagle演算法。

使用setsockopt()讓time_wait改變。

1. 如果在已經處於 established狀態下的socket(一般由埠號和標誌符區分)呼叫

closesocket(一般不會立即關閉而經歷time_wait的過程)後想繼續重用該socket:

bool breuseaddr=true;

setsockopt(s,sol_socket ,so_reuseaddr,(const char*)&breuseaddr,sizeof(bool));

2. 如果要已經處於連線狀態的soket在呼叫closesocket後強制關閉,不經歷

time_wait的過程:

bool bdontlinger = false;

setsockopt(s,sol_socket,so_dontlinger,(const char*)&bdontlinger,sizeof(bool));

setsockopt()函式的功能很強大,這裡只說了它對於time_wait的幫助。

方式二、

修改 /etc/sysctl.conf檔案;

#對於乙個新建連線,核心要傳送多少個 syn 連線請求才決定放棄,不應該大於255,預設值是5,對應於180秒左右時間   

net.ipv4.tcp_syn_retries=2  

#net.ipv4.tcp_synack_retries=2  

#表示當keepalive起用的時候,tcp傳送keepalive訊息的頻度。預設是2小時,改為300秒  

net.ipv4.tcp_keepalive_time=1200  

net.ipv4.tcp_orphan_retries=3  

#表示如果套接字由本端要求關閉,這個引數決定了它保持在fin-wait-2狀態的時間  

net.ipv4.tcp_fin_timeout=30    

#表示syn佇列的長度,預設為1024,加大佇列長度為8192,可以容納更多等待連線的網路連線數。  

net.ipv4.tcp_max_syn_backlog = 4096  

#表示開啟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  

##減少超時前的探測次數   

net.ipv4.tcp_keepalive_probes=5   

##優化網路裝置接收佇列   

net.core.netdev_max_backlog=3000   

修改完之後執行/sbin/sysctl -p讓引數生效。

這裡頭主要注意到的是net.ipv4.tcp_tw_reuse

net.ipv4.tcp_tw_recycle

net.ipv4.tcp_fin_timeout

net.ipv4.tcp_keepalive_*

這幾個引數。

net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的開啟都是為了**處於time_wait狀態的資源。

net.ipv4.tcp_fin_timeout這個時間可以減少在異常情況下伺服器從fin-wait-2轉到time_wait的時間。

net.ipv4.tcp_keepalive_*一系列引數,是用來設定伺服器檢測連線存活的相關配置。

關於keepalive的用途可以參考:

本文出自 「痕跡」 部落格,請務必保留此出處

TIME WAIT狀態的意義

客戶端與伺服器端建立tcp ip連線後關閉socket後,伺服器端連線的埠 狀態為time wait 是不是所有執行主動關閉的socket都會進入time wait狀態呢?有沒有什麼情況使主動關閉的socket直接進入closed狀態呢?主動關閉的一方在傳送最後乙個ack 後 就會進入time wa...

TIME WAIT狀態釋疑

一 現象 登陸伺服器的時候輸入netstat natup 發現存在大量time wait狀態的連線 tcp 0 0 127.0.0.1 3306 127.0.0.1 41378 time wait tcp 0 0 127.0.0.1 3306 127.0.0.1 41379 time wait tc...

TIME WAIT狀態全是3306解決辦法

剛吃完晚飯,手機簡訊一直響個不停,開啟一看全是告警資訊,立即開啟電腦檢視,發現很多網頁很不穩定 一會能開啟,一會打不開 登入伺服器檢視負載情況,cpu 記憶體 磁碟io 負載都不高,檢視日誌發現nginx有大量的502錯誤,首先懷疑是nginx呼叫後端的php程 序出問題了。為了不影響業務,我先嘗試...