2020-07-27

此為臨時(shí)鏈接更鲁,僅用于預(yù)覽谴蔑,將在短期內(nèi)失效烘豹。[關(guān)閉](javascript:;)

關(guān)于OKHttp的一些經(jīng)驗(yàn)總結(jié)

言錫 [言錫](javascript:void(0);) 7月5日

從問題出發(fā)喂江,學(xué)習(xí)OkHttp。

這篇文章從問題的背景開始悴能,圍繞OkHttp介紹該問題的解決方案揣钦,OkHttp的部分源碼解讀以及其中涉及的技術(shù)點(diǎn)。

01

背景

自己owner的一個(gè)服務(wù)漠酿,在國(guó)外機(jī)房經(jīng)常出現(xiàn)調(diào)用第三方連接超時(shí)的異常冯凹。前段時(shí)間忙于其他工作沒空理它,直到最近收到了用戶的幾例反饋炒嘲,才下決心要解決這個(gè)問題宇姚。

這個(gè)服務(wù)是一個(gè)dubbo服務(wù),為其上層應(yīng)用提供數(shù)據(jù)支持夫凸。數(shù)據(jù)來源于第三方浑劳,服務(wù)中使用了OkHttp框架調(diào)用第3方。服務(wù)的單臺(tái)實(shí)例調(diào)用第3方的qps在5000左右夭拌。

下面是創(chuàng)建OkHttpClient實(shí)例的方法魔熏,httpClient  作為OkHttpClient的單例存在衷咽。
httpClient = new OkHttpClient.Build()
我在日志中發(fā)現(xiàn)的異常信息如下:
image
可以很明顯的看到,連接超時(shí)了蒜绽。[](http://mp.weixin.qq.com/s?__biz=MjM5NDAwMTA2MA==&mid=2695729815&idx=1&sn=7c7feb801bfb8fcf5dfe4e782a4ba3c1&chksm=83d74b5cb4a0c24a21e621ed3428fd808e80c2c5e806a8162cceee62a5930b0430d5506e0f8c&scene=21#wechat_redirect)

02

解決過程

從日志中看到的信息不難得出初步的結(jié)論镶骗,第3方的服務(wù)有問題。所以馬上聯(lián)系了他們躲雅,讓他們排查鼎姊。最后給出的結(jié)論是他們?cè)诤臀覀兿嗤瑱C(jī)器配置下,ab測(cè)試單機(jī)能夠達(dá)到5000qps吏夯,沒有出現(xiàn)我們?nèi)罩局械倪B接超時(shí)錯(cuò)誤此蜈。第3方建議我們自己排查一下即横。

首先噪生,我找運(yùn)維確認(rèn)了我們的vip以及后面的網(wǎng)關(guān)集群有沒有問題,得到的反饋是vip目前負(fù)載較低东囚,沒有出現(xiàn)問題跺嗽。

其次,需要排除下部署服務(wù)的機(jī)器有沒有問題页藻,會(huì)不會(huì)是帶寬不夠桨嫁,因?yàn)榉?wù)不僅要調(diào)第3方,還要接受上層應(yīng)用的請(qǐng)求份帐。我發(fā)現(xiàn)進(jìn)入服務(wù)的單臺(tái)機(jī)器流量在200Mbps左右璃吧,出口流量在50Mbps。也沒有發(fā)現(xiàn)問題废境。

最后畜挨,只能懷疑是自己的代碼方面的問題了。從代碼來看噩凹,只能是網(wǎng)絡(luò)方面的OkHttpClient的參數(shù)配置有問題了巴元。

第一個(gè)發(fā)現(xiàn)的問題是自己沒有指定線程池,而OkHttpClient默認(rèn)的是線程池是:
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 

可以看到驮宴,線程池的最大線程數(shù)是Integer的最大值逮刨,意味著可以無限增加線程,顯然是不合理的堵泽。另外再通過查找資料修己,我配置了連接池,最大請(qǐng)求數(shù)等參數(shù)迎罗,最終的OkHttpClient配置如下:

ExecutorService executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));

重啟應(yīng)用后睬愤,日志中已經(jīng)沒有看到連接超時(shí)的log了,并且消除了很多TCP中的timewait狀態(tài)佳谦,說明連接得以復(fù)用了戴涝,網(wǎng)絡(luò)性能大幅提升。

image

03

參數(shù)詳解

| 參數(shù)
| 說明
| 備注
|
| executorService
| 執(zhí)行http請(qǐng)求的線程池 | 通過自定義線程池,可以預(yù)估請(qǐng)求量啥刻,從而設(shè)置一個(gè)適合業(yè)務(wù)的值奸鸯。默認(rèn)線程池是可以無限創(chuàng)建線程的,如果把控不好可帽,會(huì)導(dǎo)致系統(tǒng)資源耗盡娄涩。
|
| MAX_IDLE_CONNECTIONS | 連接池的大小
| 默認(rèn)是5,這個(gè)值可以設(shè)置為請(qǐng)求其他系統(tǒng)的qps
|
| KEEP_ALIVE_DURATION | 連接池中的連接的最大時(shí)長(zhǎng)
| 默認(rèn)5分鐘映跟,根據(jù)業(yè)務(wù)場(chǎng)景不同而設(shè)置
|
| DEFAULT_CONNECT_TIMEOUT | 連接超時(shí)時(shí)間
| 默認(rèn)10秒
|
| DEFAULT_READ_TIMEOUT | 讀超市時(shí)間
| 默認(rèn)10秒蓄拣,如果是流式讀,需要設(shè)置長(zhǎng)一點(diǎn)
|
| MAX_REQUEST | OKhttpClient實(shí)例最大的并發(fā)請(qǐng)求數(shù)
| 默認(rèn)64努隙,根據(jù)業(yè)務(wù)需要設(shè)置球恤。一般要大于等于MAX_REQUEST_PER_HOST,如果小于的話,那請(qǐng)求3方的最大并發(fā)不會(huì)超過MAX_REQUEST荸镊。同時(shí)需要考慮線程池的大小
|
| MAX_REQUEST_PER_HOST | 對(duì)單個(gè)被請(qǐng)求方域名的最大請(qǐng)求并發(fā)數(shù)
|

默認(rèn)4咽斧,需要考慮幾點(diǎn):

1,如果被調(diào)用方所支持的最大qps只有500躬存,那么這個(gè)值設(shè)置不要超過500

2张惹,如果okhttpClient實(shí)例只調(diào)用一個(gè)3方服務(wù),那么這個(gè)值建議設(shè)置為和MAX_REQUEST一致

3岭洲,如果okhttpClient要調(diào)用n個(gè)3方宛逗,那么建議n * MAX_REQUEST_PER_HOST接近MAX_REQUEST

同時(shí),需要結(jié)合上述線程池的大小合理設(shè)置

|

04

源碼解讀

[圖片上傳失敗...(image-b23fb4-1595856859249)]

微信掃一掃
關(guān)注該公眾號(hào)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盾剩,一起剝皮案震驚了整個(gè)濱河市雷激,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彪腔,老刑警劉巖侥锦,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異德挣,居然都是意外死亡恭垦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門格嗅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來番挺,“玉大人,你說我怎么就攤上這事屯掖⌒兀” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵贴铜,是天一觀的道長(zhǎng)粪摘。 經(jīng)常有香客問我瀑晒,道長(zhǎng),這世上最難降的妖魔是什么徘意? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任苔悦,我火速辦了婚禮,結(jié)果婚禮上椎咧,老公的妹妹穿的比我還像新娘玖详。我一直安慰自己,他們只是感情好勤讽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布蟋座。 她就那樣靜靜地躺著,像睡著了一般脚牍。 火紅的嫁衣襯著肌膚如雪向臀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天莫矗,我揣著相機(jī)與錄音飒硅,去河邊找鬼。 笑死作谚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庵芭。 我是一名探鬼主播妹懒,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼双吆!你這毒婦竟也來了眨唬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤好乐,失蹤者是張志新(化名)和其女友劉穎匾竿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔚万,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岭妖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了反璃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昵慌。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淮蜈,靈堂內(nèi)的尸體忽然破棺而出斋攀,到底是詐尸還是另有隱情,我是刑警寧澤梧田,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布淳蔼,位于F島的核電站侧蘸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鹉梨。R本人自食惡果不足惜闺魏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俯画。 院中可真熱鬧析桥,春花似錦、人聲如沸艰垂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜憎。三九已至娩怎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胰柑,已是汗流浹背截亦。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柬讨,地道東北人崩瓤。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像踩官,于是被迫代替她去往敵國(guó)和親却桶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349