中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

OkHttp3 架構(gòu)分析

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

我們都知道在OkHttp3中,其靈活性,很大程度上體現(xiàn)在,我們可以 intercept 其任意一個(gè)環(huán)節(jié),而這個(gè)優(yōu)勢(shì)便是okhttp3整個(gè)請(qǐng)求響應(yīng)架構(gòu)體系的精髓所在:

  • 在OkHttp3中,每一個(gè)請(qǐng)求任務(wù)都封裝為一個(gè) Call ,其實(shí)現(xiàn)為 RealCall 。
  • 而所有的策略幾乎都可以通過(guò) OkHttpClient 傳入
  • 所有全局策略與數(shù)據(jù),除了存儲(chǔ)在允許上層訪問(wèn)的 OkHttpClient 實(shí)例以外,還有一部分是存儲(chǔ)在只允許包可見(jiàn)的 Internal.instance 中(如連接池、路由黑名單等)
  • OkHttp中用戶可傳入的 interceptor 分為兩類,一類是全局 interceptor ,該類 interceptor 在請(qǐng)求開(kāi)始之前最早被調(diào)用,另外一類為非網(wǎng)頁(yè)請(qǐng)求的 networkInterceptor ,這類 interceptor 只有在非網(wǎng)頁(yè)請(qǐng)求中會(huì)被調(diào)用,并且是在組裝完成請(qǐng)求之后,真正發(fā)起請(qǐng)求之前被調(diào)用(這塊具體可以參看 RealCall#getResponseWithInterceptorChain() 方法)
  • 整個(gè)請(qǐng)求過(guò)程通過(guò)遞歸 RealInterceptorChain#proceed 來(lái)實(shí)現(xiàn),在每個(gè) interceptor 中調(diào)用遞歸到下一個(gè) interceptor 來(lái)完成整個(gè)請(qǐng)求流程,并且在遞歸回到當(dāng)前 interceptor 后完成響應(yīng)處理
  • 在異步請(qǐng)求中,我們通過(guò) Callback 來(lái)獲得簡(jiǎn)單清晰的請(qǐng)求回調(diào)( onFailure 、 onResponse )
  • 但是在 OkHttpClient 中,我們可以傳入 EventListener 的工廠方法,為每一個(gè)請(qǐng)求創(chuàng)建一個(gè) EventListener ,來(lái)接收非常細(xì)的事件回調(diào)

連接池

我們知道在OkHttp3存在連接池,并且該連接池是通過(guò)與 StreamAllocation 的配合完成連接池的維護(hù)。

  • 所有的請(qǐng)求連接都會(huì)通過(guò) StreamAllocation 進(jìn)行獲得,并且結(jié)合 ConnectionPool 進(jìn)行引用計(jì)數(shù),來(lái)有效緩存連接
  • 而在 StreamAllocation 中,通過(guò) RouteSelector 來(lái)根據(jù)請(qǐng)求地址進(jìn)行路由處理,期間就涉及到了 DNS解析 、 協(xié)議處理 、 代理選擇 、 簽名校驗(yàn) 等

默認(rèn)連接池策略:

  • 最多64個(gè)請(qǐng)求
  • 同一個(gè)host最多5個(gè)請(qǐng)求
  • 連接最長(zhǎng)閑置5分鐘
  • 異步連接所在線程池名: OkHttp Dispatcher
  • 常駐清理連接線程池: OkHttp ConnectionPool

獲得連接

連接池

II. 各類線程池分析

OkHttp中的對(duì)所有的任務(wù)采用 NamedRunnable ,與我開(kāi)源的 ThreadDebugger 中通過(guò)架構(gòu)層面約束,讓每個(gè)執(zhí)行單元給出對(duì)應(yīng)的業(yè)務(wù)名稱,以便于線程維護(hù)不謀而合。關(guān)于Android中 ThreadPoolExecutor 的機(jī)制,可以看我之前寫(xiě)的這篇文章。

1. 異步請(qǐng)求線程池

該線程池名 OkHttp Dispatcher ,該線程用于執(zhí)行異步的請(qǐng)求任務(wù)。

  • 該線程池本身: 無(wú)任務(wù)上限,自動(dòng)回收閑置60s的線程
  • 但是 Dispatcher 中在進(jìn)口進(jìn)行把關(guān)控制,默認(rèn)情況下保證在當(dāng)前進(jìn)程中 OkHttpClient 最多只有64個(gè)請(qǐng)求,池子中相同host的請(qǐng)求不超過(guò)5個(gè)
  • 架構(gòu)上通過(guò)兩個(gè)雙端隊(duì)列( readyAsyncCalls:Deque<AsyncCall> 與 runningAsyncCals:Dequeue<AsyncCall> )分別用于維護(hù)等待中的任務(wù)與運(yùn)行中的任務(wù)
  • 在每一個(gè)異步任務(wù)后,都會(huì)檢查一遍 readyAsyncCalls ,在滿足條件下,將最先進(jìn)入隊(duì)列的任務(wù)丟入該線程池進(jìn)行執(zhí)行

2. 連接池清理線程池

該線程池名 OkHttp ConnectionPool ,該線程用于自動(dòng)清理長(zhǎng)時(shí)間閑置或泄漏的連接。

  • 該線程本身: 無(wú)任務(wù)上限,自動(dòng)回收閑置60s的線程
  • 但是 ConnectionPool 中通過(guò)一個(gè) cleanupRunning 的標(biāo)記,控制當(dāng)前僅有一個(gè)清理任務(wù)進(jìn)入隊(duì)列
  • 清理任務(wù),會(huì)不斷清理,在所有需要清理的連接都清理完成后,會(huì)計(jì)算出最近一次需要清理的時(shí)間并阻塞,不斷清理直到連接池中沒(méi)有任何連接,方才結(jié)束
  • 在每次有連接加入連接池時(shí),如果當(dāng)前沒(méi)有清理任務(wù)運(yùn)行,會(huì)加入一個(gè)清理任務(wù)到清理線程池中執(zhí)行

3. 緩存整理線程池

該線程池名 OkHttp DiskLruCache ,該線程池用于整理本地請(qǐng)求結(jié)果的緩存。

  • 該線程池本身: 最多1個(gè)運(yùn)行中線程,其余任務(wù)會(huì)阻塞住等待,回收閑置60s的線程
  • 由于可運(yùn)行僅為一個(gè)線程,因此所有操作無(wú)需考慮線程安全問(wèn)題
  • 緩存的整理包含: 達(dá)到閥值大小的文件,刪除最近最少使用的記錄;在有關(guān)操作達(dá)到一定數(shù)量以后對(duì)記錄進(jìn)行重建

4. HTTP2異步事務(wù)線程池

該線程池名 OkHttp Http2Connection ,我們都知道HTTP2采用了多路復(fù)用(相關(guān)知識(shí)可以翻看這篇文章),因此需要維護(hù)連接有效性,本線程池就是用于維護(hù)相關(guān)的各類HTTP2事務(wù)

  • 該線程池本身: 無(wú)任務(wù)上限,自動(dòng)回收閑置60s的線程
  • 每一個(gè)HTTP2連接都有這么一個(gè)線程池存在

回望 FileDownloader ,有一個(gè)極大的痛點(diǎn)是,在最早其就引入了多進(jìn)程,雖然在后期實(shí)現(xiàn)了單進(jìn)程與多進(jìn)程的切換,但是整套體系不得不為該多進(jìn)程買(mǎi)單,極大的增加了相關(guān)的復(fù)雜度,以及無(wú)法輕量的同步回調(diào)。如果讓我再寫(xiě)一個(gè)下載引擎,我也許也會(huì)考慮分拆各個(gè)模塊,讓核心代碼保持充分的簡(jiǎn)單,也讓每個(gè)模塊足夠單一。

 

來(lái)自:https://blog.dreamtobe.cn/okhttp3-framework/

 

標(biāo)簽: dns dns解析 isp 安全 代碼

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Swift-圖像的性能優(yōu)化

下一篇:編程學(xué)習(xí)免費(fèi)教程