日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

当 HTTP 连接池遇上 KeepAlive 时

發布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 当 HTTP 连接池遇上 KeepAlive 时 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在使用netty作為http客戶端通過pool連接tomcat的時候,出現了很多Connection reset by peer 的IOException的異常。便對問題的根源做了細致的調研。

1. 連接種類

一般連接主要分為長連接,短連接和http的keepalive連接。

1.1 長連接:建立完連接后,該連接不再進行釋放。

  • 優點

    • 性能較高,不需要重復建立tcp連接或者關閉tcp連接

    • 基本上不會出現CLOSE_WAIT和TIME_WAIT的問題

  • 缺點:一般需要一個連接池來維護長連接(一般有數據庫連接池,http的連接池等) 復雜度較高

1.2 短連接:每次請求均需要tcp三次握手建立連接,業務執行,tcp四次揮手關閉連接。

  • 優點:實現簡單。

  • 缺點:

    • 性能較差。大部分都是tcp層面上的交互(新建和關閉tcp連接)

    • 系統會出現大量的tcp的狀態是:TIME_WAIT 如果沒有設置SO_RESUSEADDR ,很容易出現端口被占滿的情況。(在關閉完連接時,tcp狀態是TIME_WAIT,只有等2個MSL后,才會進行close掉)

1.3 http的keepalive:用于http協議。在http 1.1中,為了解決長連接提出的。

  • 優點:用于維護長連接,提升性能

  • 缺點:需要在header中進行控制,需要交互控制,相對復雜。

2 keepalive機制

提到keepalive, 容易對下面三種機制混淆:

  • keepalived

  • tcp 的 keepalive

  • http 的 keepalive

2.1 keepalived

用途:高可用,一般是和lvs一起使用。

具體可參考:http://outofmemory.cn/wiki/keepalived-configuration

2.2 tcp的keepalive

用途:socket連接的保活。在新建socket的時候,可以設置SO_KEEPALIVE 進行打開。

keepalive主要有三個參數:

  • tcp_keepalive_time: 一個連接需要TCP開始發送keepalive探測數據包之前的空閑時間。以秒為單位

  • tcp_keepalive_probes: 發送TCP keepalive探測數據包的最大數量,默認是9.如果發送9個keepalive探測包后對端仍然沒有響應,便發送RST關閉掉連接。

  • tcp_keepalive_intvl: 發送兩個TCP keepalive探測數據包的間隔時間,默認是75秒

2.3 http的 keepalive

用途:http的長連接,在http 1.0中使用的為短連接:每一次請求均需要新建tcp連接,http協議數據的發送接收,關閉tcp連接。 該種機制性能很 低,在http 1.1協議中引入了keepalive機制來保持tcp連接。

在http1.0中,全部是短連接,如果想建立長連接,需要在header里面加上keepalive,這樣web服務器看到這個字段,不會立馬關閉連接。而是將tcp連接維持一段時間。如果需要關閉,則在header中寫 keepalive close,來告訴 客戶端需要關閉該連接。

在http1.1中,默認會實現keepalive,如果使用的是http1.1協議,header是不需要加上keepalive的。

3. tomcat8對keepalive的實現

3.1 http 1.0實現

tomcat8中,如果發送的是http1.0的協議。 tomcat8返回的均是1.1的協議。并且不管請求的header有沒有Connection:keepalive ,均會在返回的header中加上connection:close 。下面是訪問tomcat8的截圖:

  • GET請求是http 1.0,但是返回的是1.1的協議:

    ?

  • 返回的header里面有Connection:close

    ?

3.2 http 1.1實現

tomcat8主要有兩個參數來控制keepalive的機制。keepAliveTimeout 和maxKeepAliveRequests

  • keepAliveTimeout: 默認和soTimeout 值保持一致,該值為20000ms,也就是在這么長時間內沒有通信,tomcat會關閉掉該連接。設置為-1 則代表不會關閉該連接。

  • maxKeepAliveRequests?:默認為100,也就是在keepAliveTimeout時間內,如果使用次數超過100,則會關閉掉該連接。設置為-1,則代表不會關閉連接。在關閉后,會在返回的header上面加上Connection:close 。

如果需要tomcat保持長連接:可配置 maxKeepAliveRequests = "-1" keepAliveTimeout=-"-1" ,則tomcat8不會關閉掉該連接。

4. 連接池對keepalive的處理

主要需要處理兩個地方:

  • 1:maxKeepAliveRequests?連接達到默認的設置次數。則會在header上面加Connection:close。

    • 在接收web服務器返回的數據時,需要檢查一下header里面是否有Connection:close,如果close,則需要將該連接從連接池里物理關閉掉。否則容易出現connection reset by peer的異常。

  • 2:keepAliveTimeout?超過該時間沒有流量,則會關閉掉連接。

    • tomcat在連接空閑超過該時間后,會主動關閉掉連接。會向客戶端發送FIN命令。

如果是IO(同步socket):則在獲取連接的時候需要檢查一下該socket的連接狀態。 因為tcp在底層已經關閉了該連接。 如果不檢查的話,則會SocketCloseException的錯誤。

如果是NIO(異步channel) :則在selector的時候,read數據的時候,會返回-1,然后將該連接從連接池給物理關閉掉。

5. Connection reset by peer異常

異常場景

  • 1: 當我們往一個對端已經close的通道寫數據的時候,對方的tcp會收到這個報文,并且反饋一個reset報文,當收到reset報文的時候,繼續做select讀數據的時候就會拋出Connect reset by peer的異常。該異常為jdk拋出的異常。在native代碼里面拋出。

  • 2:嘗試和未開放的服務器端口建立tcp連接時,服務器tcp將會直接向客戶端發送reset報文

  • 3:ack報文丟失,并且超出一定的重傳次數或時間后,會主動向對端發送reset報文釋放該TCP連接

連接池出現該異常分析

  • 1:由于客戶端在收到Connection:close的header時候并沒有物理關閉該連接,而是將該連接返回到了連接池中。

  • 2:下一個請求拿到該連接發送數據,由于tomcat的該socket通道已經關閉,tomcat接收到該連接時,便會回復一個RST。

  • 3:客戶端在讀取數據(RST的時候,內部會調用(JDK)SocketChannel.read的時候拋出 java.io.IOException(Connection reset by peer)

總結

以上是生活随笔為你收集整理的当 HTTP 连接池遇上 KeepAlive 时的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。