HttpClient連線池的連線保持、超時和失效機制
HTTP是一種無連線的事務協議,底層使用的還是TCP,連線池複用的就是TCP連線,目的就是在一個TCP連線上進行多次的HTTP請求從而提高效能。每次HTTP請求結束的時候,HttpClient會判斷連線是否可以保持,如果可以則交給連線管理器進行管理以備下次重用,否則直接關閉連線。這裡涉及到三個問題:
1、如何判斷連線是否可以保持?
要想保持連線,首先客戶端需要告訴伺服器希望保持長連線,這就是所謂的Keep-Alive模式(又稱持久連線,連線重用),HTTP1.0中預設是關閉的,需要在HTTP頭加入"Connection: Keep-Alive",才能啟用Keep-Alive;HTTP1.1中預設啟用Keep-Alive,加入"Connection: close ",才關閉。
但客戶端設定了Keep-Alive並不能保證連線就可以保持,這裡情況比較復。要想在一個TCP上進行多次的HTTP會話,關鍵是如何判斷一次HTTP會話結束了?非Keep-Alive模式下可以使用EOF(-1)來判斷,但Keep-Alive時伺服器不會自動斷開連線,有兩種最常見的方式。
使用Conent-Length
顧名思義,Conent-Length表示實體內容長度,客戶端(伺服器)可以根據這個值來判斷資料是否接收完成。當請求的資源是靜態的頁面或圖片,伺服器很容易知道內容的大小,但如果遇到動態的內容,或者檔案太大想多次傳送怎麼辦?
使用Transfer-Encoding
當需要一邊產生資料,一邊發給客戶端,伺服器就需要使用 Transfer-Encoding: chunked 這樣的方式來代替 Content-Length,Chunk編碼將資料分成一塊一塊的傳送。它由若干個Chunk串連而成,以一個標明長度為0 的chunk標示結束。每個Chunk分為頭部和正文兩部分,頭部內容指定正文的字元總數(十六進位制的數字 )和數量單位(一般不寫),正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF) 隔開。在最後一個長度為0的Chunk中的內容是稱為footer的內容,是一些附加的Header資訊。
對於如何判斷訊息實體的長度,實際情況還要複雜的多,可以參考這篇文章:https://zhanjindong.com/2015/05/08/http-keep-alive-header
總結下HttpClient如何判斷連線是否保持:
- 檢查返回response報文頭的Transfer-Encoding欄位,若該欄位值存在且不為chunked,則連線不保持,直接關閉。
- 檢查返回的response報文頭的Content-Length欄位,若該欄位值為空或者格式不正確(多個長度,值不是整數),則連線不保持,直接關閉。
- 檢查返回的response報文頭的Connection欄位(若該欄位不存在,則為Proxy-Connection欄位)值:
- 如果這倆欄位都不存在,則1.1版本預設為保持, 1.0版本預設為連線不保持,直接關閉。
- 如果欄位存在,若欄位值為close 則連線不保持,直接關閉;若欄位值為keep-alive則連線標記為保持。
2、 保持多長時間?
保持時間計時開始時間為連線交換至連線池的時間。 保持時長計算規則為:獲取response中 Keep-Alive欄位中timeout值,若該存在,則保持時間為 timeout值*1000,單位毫秒。若不存在,則連線保持時間設定為-1,表示為無窮。
3、保持過程中如何保證連線沒有失效?
很難保證。傳統阻塞I/O模型,只有當I/O操做的時候,socket才能響應I/O事件。當TCP連線交給連線管理器後,它可能還處於“保持連線”的狀態,但是無法監聽socket狀態和響應I/O事件。如果這時伺服器將連線關閉的話,客戶端是沒法知道這個狀態變化的,從而也無法採取適當的手段來關閉連線。
針對這種情況,HttpClient採取一個策略,通過一個後臺的監控執行緒定時的去檢查連線池中連線是否還“新鮮”,如果過期了,或者空閒了一定時間則就將其從連線池裡刪除掉。ClientConnectionManager提供了 closeExpiredConnections和closeIdleConnections兩個方法。
參考文章
相關推薦
HttpClient連線池的連線保持、超時和失效機制
HTTP是一種無連線的事務協議,底層使用的還是TCP,連線池複用的就是TCP連線,目的就是在一個TCP連線上進行多次的HTTP請求從而提高效能。每次HTTP請求結束的時候,HttpClient會判斷連線是否可以保持,如果可以則交給連線管理器進行管理以備下次重用,否則直接關閉連線。這裡涉及到三個問題: 1、如
HttpClient連接池的連接保持、超時和失效機制
默認 footer ive tcp連接 部分 i/o模型 不存在 復雜 header HTTP是一種無連接的事務協議,底層使用的還是TCP,連接池復用的就是TCP連接,目的就是在一個TCP連接上進行多次的HTTP請求從而提高性能。每次HTTP請求結束的時候,HttpClie
Hibernate的三種連線池設定C3P0、dbcp和Proxool
<!-- JDBC驅動程式 --> <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property><property name="connec
mysql筆記五——資料庫連線池(原理、構建)和java動態代理的使用
資料庫連線池 1、什麼是資料庫連線池? 資料庫連線池負責分配、管理和釋放資料庫連線,它允許應用程式重複使用一個現有的資料庫連線,而不是再重新建立一個;釋放空閒時間超過最大空閒時間的資料庫連線來避免因為沒有釋放資料庫連線而引起的資料庫連線遺漏。這項
【JDBC程式設計】Java 連線 MySQL資料庫基礎、入門和進階
Content: 常用的JDBC API 資料庫環境的搭建 建立資料庫連線 資料庫訪問優化 一. 常用的JDBC API 1. DriverManager類 : 資料庫管理類,用於管理一組JDBC驅動程式的基本服務。應用程式和資料
IM開發基礎知識補課(四):正確理解HTTP短連線中的Cookie、Session和Token
1、前言 眾所周之,IM是個典型的快速資料流交換系統,當今主流IM系統(尤其移動端IM)的資料流交換方式都是Http短連線+TCP或UDP長連線來實現。Http短連線主要用於從伺服器讀取各種持久化資訊:比如使用者資訊、聊天曆史記錄、好友列表等等,長連線則是用於實時的聊天訊息
Spring學習(四)Jdbc連線池交個spring管理和事務操作
一、連線池的配置交給Spring管理 1,新增jar包 2,spring的jdbc連線池配置 <!-- 配置連線池 --> <bean id="dataSource" class="org.spring
連線資料庫(java驅動連線和連線池連線)
使用java驅動連線資料庫: String url ="jdbc:mysql://localhost:3306/zhongruan"; String usernam
DRUID 連線池的使用、配置詳解
DRUID 連線池的使用、配置詳解 本篇參考:原文連結 一、DRUID 介紹: DRUID 是阿里巴巴開源平臺上一個資料庫連線池實現,它結合了 C3P0、DBCP、PROXOOL等DB池的優點,同時加入了日誌監控,可以很好的監控 DB 池連線和 SQL 的執行情況,可以說是針
JDBC 資料庫連線池(DBCP、C3P0) 詳解
前言 這段時間狀態有一點浮躁,希望自己靜下心來。還有特別多的東西還沒有學懂。需要學習的東西非常的多,加油! 一、JDBC複習 Java Data Base Connectivity,java資料庫連線,在需要儲存一些資料,或者拿到一些資料的時候,就需要往
JDBC(三)資料庫連線池(DBCP、C3P0)
前言 這段時間狀態有一點浮躁,希望自己靜下心來。還有特別多的東西還沒有學懂。需要學習的東西非常的多,加油! 一、JDBC複習 Java Data Base Connectivity,java資料庫連線,在需要儲存一些資料,或者拿到一些資料的時候,就需要往資料庫裡存取資料。那麼java如何連線資料
使用JDBC連線Oracle資料庫和使用連線池連線Oracle資料庫的程式碼解析
這裡連線的是oracle資料庫。 JDBC是什麼:JDBC是java資料庫連線技術的簡稱,提供連線各種常用資料庫的能力。 客戶端傳送請求給應用伺服器,應用伺服器通過JDBC連線到資料庫伺服器,查詢資料庫中的資料,返回一個結果集,再把結果集轉換成實體類傳遞給客戶端。 JDBC
如何編寫出高效的資料庫連線池(附帶完整程式碼C#和Java實現)
{ privateboolean _enable =true; //是否失效privateboolean _isUse =false; //是否正在被使用中privateboolean _allot =true; //表示該連線是否可以被分配private Date _createTime; //建立時
Java框架資料庫連線池比較(c3p0,dbcp和proxool)
現在常用的開源資料連線池主要有c3p0,dbcp和proxool三種,其中: ¨ hibernate開發組推薦使用c3p0; ¨ spring開發組推薦使用dbcp (dbcp連線池有weblogic連線池同樣的問題,就是強行關閉連
實現高效的資料庫連線池(附帶完整程式碼C#和Java實現)
{ privateboolean _enable =true; //是否失效privateboolean _isUse =false; //是否正在被使用中privateboolean _allot =true; //表示該連線是否可以被分配private Date _createTime; //建立時
資料庫連線池中比較一下ArrayList和LinkedList
在我們專案中的jdbc 連結中,我們一般會用到資料庫連線池的這麼東東,list // 資料庫連線池 private LinkedList<Connection> datasource = new LinkedList<Connection>();
JDBC資料庫連線池連線資料庫及資料庫操作DAO層設計通用更新及查詢方法(二)
上篇文章主要介紹了通過資料庫連線池連線資料庫,然後設計了對資料庫通用更新和查詢方法,本篇文章主要通過例項介紹上篇文章定義的對資料庫操作的幾個方法的使用: 首先我們先在資料庫建立一個學生資訊表Student欄位如圖: 建立好表將配置檔案的資訊改好然後需要建立一
JDBC資料庫連線池連線資料庫及資料庫操作DAO層設計通用更新及查詢方法(一)
該篇文章介紹了資料庫連線池獲取資料庫連線以及資料庫操作的基本使用,然後主要提供了java專案案例中dao層的一種設計,利用反射的原理定義了通用的查詢方法可以對應所有的表和例項。文章中的每段程式碼都提供了詳細的註釋及邏輯步驟 首先匯入資料庫連線的所需要的jar包:
Mybatis 搭配 阿里druid連線池 連線 oracle 或 mysql
DRUID介紹 DRUID是阿里巴巴開源平臺上一個資料庫連線池實現,它結合了C3P0、DBCP、PROXOOL等DB池的優點,同時加入了日誌監控,可以很好的監控DB池連線和SQL的執行情況,可以說是針對監控而生的DB連線池(據說是目前最好的連線池,不知道速
Nodejs:連線池連線mysql
OptPool.js var mysql = require("mysql");//呼叫mysql模組 function OptPool() { this.flag = true;//是否連線過 this.pool = mysql.createPool({