OkHttp源碼徹底解析(五)OkHttp連接池

 

本系列文章:

OkHttp源碼徹底解析(一)OkHttp請求流程

OkHttp源碼徹底解析(二)OkHttp架構及API源碼

OkHttp源碼徹底解析(三)OkHttp3.0攔截器原理——責任鏈模式

OkHttp源碼徹底解析(四)OkHttp攔截器的作用

OkHttp源碼徹底解析(五)OkHttp連接池

 

 

 

目錄

OkHttp連接池

連接池的意義——KeepAlive機制

從攔截器流程瞭解連接池

連接池ConnectionPool的創建

連接池的緩存操作


 

連接池是用來管理和複用網絡連接對象的,而網絡連接的主角就是Connection/RealConnection.

OkHttp連接池

OkHttp3將客戶端與服務器之間的連接抽象爲Connection/RealConnection,爲了管理這些連接的複用而設計了ConnectionPool。共享相同Address的請求可以複用連接

 

連接池的意義——KeepAlive機制

複用連接,減少了頻繁的網絡請求導致性能下降的問題。我們知道,Http是基於TCP協議的,而TCP建立連接需要經過三次握手,斷開需要經過四次揮手,因此,Http中添加了一種KeepAlive機制,當數據傳輸完畢後仍然保持連接,等待下一次請求時直接複用該連接。

一次響應的流程

在高併發的請求連接情況下或者同個客戶端多次頻繁的請求操作,無限制的創建會導致性能低下。

如果使用keep-alive

timeout空閒時間內,連接不會關閉,相同重複的request將複用原先的connection,減少握手的次數,大幅提高效率。

並非keep-alive的timeout設置時間越長,就越能提升性能。長久不關閉會造成過多的殭屍連接和泄露連接出現。

 

 

從攔截器流程瞭解連接池

在講解連接池之前,先了解OkHttp的攔截器

OkHttp攔截器流程圖

 

 

上面的攔截器分別是:

1.失敗重連攔截器:
一個循環來不停的獲取response。每循環一次都會獲取下一個request,如果沒有,則返回response,退出循環。而獲取下一個request的邏輯,是根據上一個response返回的狀態碼,分別作處理。

2.橋接攔截器:

請求從應用層數據類型類型轉化爲網絡調用層的數據類型。將網絡層返回的數據類型 轉化爲 應用層數據類型。(補足缺失的請求頭等)

3.緩存攔截器:

CacheInterceptor主要作用是將請求 和 返回 關連得保存到緩存中。客戶端與服務端根據一定的機制,在需要的時候使用緩存的數據作爲網絡請求的響應,節省了時間和帶寬。

4.連接攔截器 

與請求服務器的攔截器是網絡交互的關鍵。爲請求服務器攔截器建立可用的連接,創建用於網絡IO流  的RealConnection對象

5.請求服務器的攔截器:

完成了最後發起網絡請求的工作。將HTTP請求寫入網絡IO流,從IO流讀取網絡數據

與連接攔截器要劃分爲兩個攔截器,除了解耦之外,更重要的是在這兩個流程之間還可以插入一個專門爲WebSocket服務的攔截器( WebSocket一種在單個 TCP 連接上進行全雙工通訊的協議,本文不做詳解)。
關於這部分不具體展開,感興趣可以看我的另外兩篇博客,可以說是非常詳細地介紹了攔截器的原理及應用

OkHttp攔截器

攔截器原理

 

 

其中,與連接池相關的是失敗重連攔截器連接攔截器

1.RetryAndFollowUpInterceptor將創建的StreamAllocation對象傳遞給後面執行的Interceptor

2.ConnectInterceptorRealInterceptorChain獲取前面的Interceptor傳過來的StreamAllocation對象,執行 streamAllocation.newStream() 完成前述所有的連接建立工作,創建的用於網絡IO的RealConnection對象,以及對於與服務器交互最爲關鍵的HttpCodec等對象傳遞給後面的Interceptor,也就是CallServerInterceptor

 

streamAllocation.newStream()新建了IO流,將請求序列化發到網絡,將網絡數據反序列化並接收(請求服務器的攔截器)

RealConnection底層連接着Socket,就是實現了跨進程與網絡上其他設備交互的底層實現。

 

 

 

連接池ConnectionPool的創建

OkHttp3的用戶可以自行創建ConnectionPool,對最大空閒連接數及連接的保活時間進行配置,並在OkHttpClient創建期間,將其傳給OkHttpClient.Builder,在OkHttpClient中啓用它。沒有定製連接池的情況下,則在OkHttpClient.Builder構造過程中以默認參數

默認情況下,ConnectionPool 最多保存 5個 處於空閒狀態的連接,且連接的默認保活時間爲 5分鐘。也就是默認支持5個併發Socket連接,默認的keepAlive時間爲5分鐘,當然我們可以在構建OkHttpClient時設置不同的值

 

連接池的緩存操作

ConnectionPool提供對Deque<RealConnection>進行操作的方法分別爲putgetconnectionBecameIdleevictAll幾個操作。分別對應放入連接、獲取連接、移除連接、移除所有連接操作。

遍歷connections緩存列表,當某個連接計數的次數小於限制的大小以及request的地址和緩存列表中此連接的地址完全匹配。則直接複用緩存列表中的connection作爲request的連接。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章