1. 程式人生 > >APP應用 HTTP/1.0中keep-alive

APP應用 HTTP/1.0中keep-alive

   

 

在HTTP/1.0中keep-alive不是標準協議,客戶端必須傳送Connection:Keep-Alive來啟用keep-alive連線。 https://www.imooc.com/article/31231   HTTP協議是無狀態的協議,即每一次請求都是互相獨立的。因此它的最初實現是,每一個http請求都會開啟一個tcp socket連線,當互動完畢後會關閉這個連線。   HTTP協議是全雙工的協議,所以建立連線與斷開連線是要經過三次握手與四次揮手的。顯然在這種設計中,每次傳送Http請求都會消耗很多的額外資源,即連線的建立與銷燬。
  於是,HTTP協議的也進行了發展,通過持久連線的方法來進行socket連線複用。  

 

從圖中可以看到:
  1. 在序列連線中,每次互動都要開啟關閉連線
  2. 在持久連線中,第一次互動會開啟連線,互動結束後連線並不關閉,下次互動就省去了建立連線的過程。
  持久連線的實現有兩種:HTTP/1.0+的keep-alive與HTTP/1.1的持久連線。   HTTP/1.1的連線預設情況下都是持久連線。如果要顯式關閉,需要在報文中加上Connection:Close首部。不傳送Connection:Close不意味著伺服器承諾連線永遠保持開啟。即在HTTP/1.1中,所有的連線都進行了複用。
HttpClien中使用了連線池來管理持有連線,同一條TCP鏈路上,連線是可以複用的。HttpClient通過連線池的方式進行連線持久化。   其實“池”技術是一種通用的設計,其設計思想並不複雜:
  1. 當有連線第一次使用的時候建立連線
  2. 結束時對應連線不關閉,歸還到池中
  3. 下次同個目的的連線可從池中獲取一個可用連線
  4. 定期清理過期連線 如下:
在HttpClient4.4版本之前,在從連線池中獲取重用連線的時候會檢查下是否過期,過期則清理。 之後的版本則不同,會有一個單獨的執行緒來掃描連線池中的連線,發現有離最近一次使用超過設定的時間後,就會清理。預設的超時時間是2秒鐘。
總結
  • HTTP協議通過持久連線的方式,減輕了早期設計中的過多連線問題
  • 持久連線有兩種方式:HTTP/1.0+的Keep-Avlive與HTTP/1.1的預設持久連線
  • HttpClient通過連線池來管理持久連線,連線池分為兩個,一個是總連線池,一個是每個route對應的連線池
  • 預設連線重用策略與HTTP協議約束一致,根據response先判斷Connection:Close則關閉,在判斷Connection:Keep-Alive則開啟,最後版本大於1.0則開啟
  • 只有在HttpClientBuilder中手動開啟了清理過期與空閒連線的開關後,才會清理連線池中的連線
  • HttpClient4.4之後的版本通過一個死迴圈執行緒清理過期與空閒連線,該執行緒每次執行都sleep一會,以達到定期執行的效果