TCP半鏈接和全鏈接問題html
TCP握手過程詳解算法
如上圖所示,關鍵部分:syns queue(半鏈接隊列)和accept queue(全鏈接隊列)數據庫
正常狀況下的處理過程以下:apache
1)當server端收到client發送的SYN後,將鏈接相關信息放在syns queue中,並回復SYN+ACK;centos
2)當server端收到client發送的ACK後,將鏈接相關信息從syns queue中取出並放在accept queue中。服務器
異常狀況:併發
步驟2)中若是accept queue滿了,則根據tcp_abort_on_overflow指定的策略執行socket
若是tcp_abort_on_overflow爲0,server丟棄client發送的ack,而且在一段時間後再次發送syn+ack給client(即從新走握手的第二步),若是cilent的超時時間比較短,就會出現異常;重試次數由net.ipv4.tcp_synack_retries指定(centos默認5次);tcp
若是tcp_abort_on_overflow爲1,server將發送一個reset給client,表示要廢掉此次握手過程和鏈接。此時client應該會出現connection reset by peer異常。性能
怎麼查看隊列是否滿?
netstat -s
該命令查看每一個協議的統計數據
netstat -s | egrep "listen"
若是看到:XXXX times the listen queue of a socket overflowed 而且XXXX 值在不斷增長,就說明有全鏈接隊列偶爾滿了。
ss -lnt | grep port
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 :::9188 :::*
其中Send-Q爲監聽9188端口的全鏈接隊列最大爲50,Recv-Q表示全鏈接隊列中和等待進入全鏈接的數量。
全鏈接隊列的大小取決於:min(backlog, somaxconn) . backlog是在socket建立的時候傳入的(Java Socket默認爲50),somaxconn是一個os級別的系統參數
半鏈接隊列的大小取決於:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。 不一樣版本的os會有些差別.
CLOSE-WAIT問題
什麼狀況下會出現CLOSE-WAIT狀態
在被動關閉鏈接時,已經收到對方發來的FIN(併發送了ACK),但尚未發送本身的FIN時,處於CLOSE_WAIT狀態。
正常狀況下該狀態持續的時間應該很短,出現大量close_wait的現象,主要緣由是某種狀況下對方關閉了socket連接,可是我方忙與讀或者寫,沒有關閉鏈接。
產生該問題的例子:https://blog.csdn.net/yu616568/article/details/44677985
首先,我這邊的大部分請求都須要查詢數據庫,個人數據庫鏈接池設置的最大鏈接數是100,因此每個請求建立了一個鏈接,等到100個請求就把鏈接池佔滿了,可是處理servlet的那個線程並無釋放這個鏈接,因而接下來的請求再去建立數據庫鏈接的時候就會一直阻塞在那裏,這裏我所用的是DBCP做爲鏈接池的,它的實現好像是使用apache的objectPool來實現的,若是沒有可用的鏈接對象會致使線程等待,好了,servlet因爲得不到數據庫鏈接而阻塞了,這個客戶端的請求就一直等待,客戶端使用httpclient設置了5s的請求超時時間,那麼超時以後就會拋出異常,關閉鏈接,關閉鏈接致使客戶端發送了FIN報文,我這邊的TCP/IP返回了ACK報文,可是因爲處理請求的線程還處於阻塞的狀態,因此當前的鏈接狀態時CLOSE_WAIT。
解決方法
基本的思想就是要檢測出對方已經關閉的socket,而後關閉它
1.代碼須要判斷socket,一旦read返回0,斷開鏈接,read返回負,檢查一下errno,若是不是AGAIN,也斷開鏈接。(注:在UNP 7.5節的圖7.6中,能夠看到使用select可以檢測出對方發送了FIN,再根據這條規則就能夠處理CLOSE_WAIT的鏈接)
2.給每個socket設置一個時間戳last_update,每接收或者是發送成功數據,就用當前時間更新這個時間戳。按期檢查全部的時間戳,若是時間戳與當前時間差值超過必定的閾值,就關閉這個socket。
3.使用一個Heart-Beat線程,按期向socket發送指定格式的心跳數據包,若是接收到對方的RST報文,說明對方已經關閉了socket,那麼咱們也關閉這個socket。
4.設置SO_KEEPALIVE選項,並修改內核參數
TCP協議在帶寬利用率、性能方面的優化
delay ack
Nagle算法
參考資料