搜尋系統16:從HttpClient學習連線池

一.HttpClient請求的一般過程

1。拿連線

搜尋系統16:從HttpClient學習連線池

2。與伺服器建立連線(new Socket)

搜尋系統16:從HttpClient學習連線池

3。從服務獲取結果

搜尋系統16:從HttpClient學習連線池

4。keepAlive的判斷

在程式碼org。apache。http。impl。execchain。MainClientExec裡請求結束後(requestExecutor。execute),用策略模式來判斷是否keepAlive

if (reuseStrategy。keepAlive(response, context))

從以下實現可以看出,keepAlive的標誌是從Response的Header中取得的

搜尋系統16:從HttpClient學習連線池

還有最後一句,如果header裡沒,http版本號大於1。0,也會保持連線。

如果沒有keepAlive那麼就會執行connHolder。markNonReusable,這個就是把ConnectHolder的reusable置為false。不過我測試了很多的網站,都返回了Keep-Alive,應該都可以保持連線一段時間。

5。歸還連線

在ConnectionHolder類裡可以看到以下程式碼:

搜尋系統16:從HttpClient學習連線池

如果reusable=false,也就是沒有keepalive,就會關閉連線。

二、http請求頭的格式怎麼獲取?

以訪問https://www。baidu。com為例:

在程式碼org。apache。http。impl。io。SessionOutputBufferImpl。flushBuffer方法內打斷點

搜尋系統16:從HttpClient學習連線池

三、連線是否被連線池複用了?

連續兩次請求同一個地址,在程式碼AbstractConnPool。AbstractConnPool。getPool裡檢視第三次執行情況,直接從連線池裡取出了物件則被複用了,否則沒有。這裡被複用了並不意味著能執行成功,還要看伺服器是否關閉了連線。為什麼是第三次,因為一次請求會在leaseConnection和releaseConnection呼叫這個getPool方法,共兩次,所以第二次請求是第三次。

搜尋系統16:從HttpClient學習連線池

再看一下這個HttpRoute物件的hashcode方法,恩,就是這些因素決定了是不是同一個請求。

搜尋系統16:從HttpClient學習連線池