OkHttp——連接池管理(6)

OkHttp分層結構

OkHttp 分層結構如下圖所示,其中連接池部分位於我們的最底層連接層中。
OkHttp

在 OkHttp的攔截器中最後兩個攔截器ConnectInterceptor 、 CallServerInterceptor 分別用於打開連接和從當前連接中寫入和讀取數據,而連接池就處於獲取連接的StreamAllocation和讀寫數據的Okio的中間。
其中StreamAllocation 在建立連接的過程中起着非常關鍵的作用,下面我們看一看這類的作用吧.
在這裏插入圖片描述

中流砥柱之StreamAllocation

StreamAllocation 處於上層請求和底層連接池直接 , 協調請求和連接池直接的關係。我們在之前的攔截器一塊說過,StreamAllocation是在第一個攔截器RetryAndFollowUpInterceptor中創建的。
由於是在攔截器中創建的,那意味着每一次請求創建了一個 StreamAllocation 對象,那麼問題來了? 之前我們說過每一個 OkHttpClient 對象只有一個對應的連接池, 剛剛又說到 StreamAllocation 打開連接, 那麼 StreamAllocation 是如何創建連接池的呢?我們很容易就去 StreamAllocation 中找連接池創建的邏輯,但是找不到。 連接池創建的地方在 OkHttpClient 中(我們的客戶端中)。
OkHttpClient 默認構造函數的 Builder , 在這裏創建了連接池。所以這裏我們也可以看到, 如果我們對默認連接池不滿,我們是可以直通過 builder 接指定的。
搞懂了 StreamAllocation 和 ConnectionPool 的創建 , 我們再來看看 StreamAllocation 是怎麼打開連接的?
下面是一個創建連接的過程:
在這裏插入圖片描述
從上圖可以看出 StreamAllocation 在獲取連接的時候首先是去連接池中獲取連接的,那我們就下來就看看連接池。

連接池 ConnectionPool

我們都知道Http協議的底層是TCP協議,TCP 連接的創建和斷開是有性能開銷的,在 Http1.0 中,每一次請求就打開一個連接,在一些老的舊的瀏覽器上,如果還是基於 Http1.0,體驗會非常差; Http1.1 以後支持長連接, 運行一個請求打開連接完成請求後, 連接可以不關閉, 下次請求時複用此連接,從而提高連接的利用率。當然並不是連接打開後一直開着不關,這樣又會造成連接浪費,怎麼管理?
在OKHttp3 的默認實現中,使用一個雙端隊列來緩存所有連接, 這些連接中最空閒時間已經超過了keep-alive指定的時間就要移除了。

在這裏插入圖片描述
ConnectionPool 主要提供一個雙向列表來存取連接, 使用一個定時任務定期清理無用連接。 而連接的創建和複用邏輯主要在 StreamAllocation 中。
StreamAllocation 主要是爲上層提供一個連接, 如果連接池中有複用的連接則複用連接, 如果沒有則創建新的,那連接池中真正存儲的連接是怎麼實現的呢?

RealConnection

OkHttp中連接的實現類是RealConnection,RealConnection是Connection的實現類,代表着鏈接socket的鏈路,如果擁有了一個RealConnection就代表了我們已經跟服務器有了一條通信鏈路,而且通過RealConnection代表是連接socket鏈路,RealConnection對象意味着我們已經跟服務端有了一條通信鏈路了。
在這裏插入圖片描述

總結

總之,連接池內存存儲着我們的連接,外部通過StreamAllocation從連接池中獲取連接(RealConnection),如果拿不到複用的連接,就創建一個新的連接,然後放入連接池中,以便下次使用。而網絡連接的建立過程是在RealConnection中實現的。連接池只是用來緩存我們的連接,節省資源。

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