最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

接口耗時(shí)2000多秒!我人麻了!

2023-06-22 12:02 作者:流浪在銀河邊緣的阿強(qiáng)  | 我要投稿

接口耗時(shí)2000多秒!我人麻了!

  • 前幾天早上,有個(gè)push服務(wù)不斷報(bào)警,報(bào)了很多次,每次都得運(yùn)維同學(xué)重啟服務(wù)來(lái)維持,因?yàn)檫@個(gè)是我負(fù)責(zé)的,所以我頓時(shí)緊張了起來(lái),匆忙來(lái)到公司,早飯也不吃了,趕緊排查!

1、 現(xiàn)象與排查步驟:

下面是下午時(shí)候幾次告警的截圖:

  • 來(lái)看下圖。。。。接口超時(shí) 2000多秒。。。。我的心碎了?。?!人也麻了!??!腦瓜子嗡嗡的。。。

  • 另外還總是報(bào)pod不健康、不可用 這些比較嚴(yán)重的警告!

我的第一反應(yīng)是調(diào)用方有群發(fā)操作,然后看了下接口的qps 貌似也不高呀!也就 9req/s, 之后我去 grafana 監(jiān)控平臺(tái) 觀察jvm信息發(fā)現(xiàn),線程數(shù)量一直往上漲,而且線程狀態(tài)是 WAITING 的也是一直漲。

如下是某一個(gè)pod的監(jiān)控:


為了觀察到底是哪個(gè)線程狀態(tài)一直在漲,我們點(diǎn)進(jìn)去看下詳情:

上圖可以看到 該pod的線程狀態(tài)圖 6種線程狀態(tài)全列出來(lái)了, 分別用不同顏色的線代表。而最高那個(gè)同時(shí)也是14點(diǎn)以后不斷遞增那個(gè)是藍(lán)線 代表的是 WAITING 狀態(tài)下的線程數(shù)量。

通過(guò)上圖現(xiàn)象,我大概知道了,肯定有線程是一直在wait ,無(wú)限wait下去,后來(lái)我找運(yùn)維同學(xué) dump了線程文件,分析一波,來(lái)看看到底是哪個(gè)地方使線程進(jìn)入了wait ??。?!

如下 是dump下來(lái)的線程文件,可以看到搜索出427個(gè)WAITING , 這也基本和 grafana 監(jiān)控中狀態(tài)是WAITTING的線程數(shù)量一致

重點(diǎn)來(lái)了(這個(gè) WAITING 狀態(tài)的堆棧信息,還都是從 IOSPushStrategy#pushMsgWithIOS 這個(gè)方法的某個(gè)地方出來(lái)的(151行出來(lái)的)),于是我們找到代碼來(lái)看看,是哪個(gè)小鬼在作怪?

而類(lèi) PushNotificationFuture 繼承了 CompletableFuture,他自己又沒(méi)有g(shù)et方法,所以本質(zhì)上 就是調(diào)用的 CompletableFuture的 get 方法。

ps:提一嘴,我們這里的場(chǎng)景是 等待ios push服務(wù)器的結(jié)果,不知道啥情況,今天(指發(fā)生故障的那天)ios push服務(wù)器(域名: api.push.apple.com )一直沒(méi)返回,所以就導(dǎo)致一直等待下去了。。

看到這, ?我 豁然開(kāi)朗 && 真相大白 ?了,原來(lái)是在使用 CompletableFutureget時(shí)候,沒(méi)設(shè)置超時(shí)時(shí)間,這樣的話會(huì)導(dǎo)致一直在等結(jié)果。。。(但代碼不是我寫(xiě)的,因?yàn)槲抑?CompletableFuture 的get不設(shè)置參數(shù)會(huì)一直等下去 ,我只是維護(hù),后期也沒(méi)怎么修改這塊的邏輯,哎 ,說(shuō)多了都是淚呀?。?/p>

好一個(gè) CompletableFuture#get();

(真是 死等啊。。。一點(diǎn)不含糊的等待下去,等的天荒地老??菔癄€也要等下去~~~ )

到此,問(wèn)題的原因找到了。

2、 修復(fù)問(wèn)題

解決辦法很簡(jiǎn)單,給CompletableFuture的get操作 加上超時(shí)時(shí)間即可,如下代碼即可修復(fù):

在修復(fù)后,截止到今天(6月8號(hào))沒(méi)有這種報(bào)警情況了,而且線程數(shù)和WAITING線程都比較穩(wěn)定,都在正常范圍內(nèi),如下截圖(一共4個(gè)pod):

至此問(wèn)題解決了~~~ 終于可以睡個(gè)好覺(jué)啦!

3、 復(fù)盤(pán)總結(jié)

3.1、 代碼淺析

既然此次的罪魁禍?zhǔn)资??CompletableFuture的get方法 ?那么我們就淺析一下 :

  1. 首先看下 get(); 方法


上邊可以看到 不帶參數(shù)的get方法: if(deadLine==0) 成立 ,也就是最終調(diào)用了LockSupport的park(this);方法,而這個(gè)方法最終調(diào)了unsafe的這個(gè)方法-> unsafe.park(false, 0L); 其中第二個(gè)參數(shù)就是等待多長(zhǎng)時(shí)間后,unpark即喚醒被掛起的線程,而0 則代表無(wú)限期等待。

  1. 再來(lái)看下 get(long timeOut,TimeUnit unit);方法

  1. 我們可以看到 帶參數(shù)的get方法: if(deadLine==0) 不成立,走的else邏輯 ?也就是最終調(diào)用了LockSupportparkNanos(this,nanos);方法,而這個(gè)方法最終調(diào)了unsafe的這個(gè)方法-> unsafe.park(false, nanos); 其中第二個(gè)參數(shù)就是你調(diào)用get時(shí),傳入的tiimeOut參數(shù)(只不過(guò)底層轉(zhuǎn)成納秒了)


    我們跑了下程序,發(fā)現(xiàn)超過(guò)指定時(shí)間后,get(long timeOut,TimeUnit unit); 方法拋出 TimeoutException異常,而至于超時(shí)后我們開(kāi)發(fā)者怎么處理,就在于具體情況了。

    java復(fù)制代碼Exception in thread "main" java.util.concurrent.TimeoutException ?? ? ? ?at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1886) ?? ? ? ?at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2021)


而在 我的另一篇文章 萬(wàn)字長(zhǎng)文分析synchroized 這篇文章中,我們其實(shí)深入過(guò)openjdk的源碼,見(jiàn)識(shí)過(guò)parkunpark操作,我們截個(gè)圖回憶一下:

3.2、最后總結(jié):

1.在調(diào)用外部接口時(shí)。一定要注意設(shè)置超時(shí)時(shí)間,防止三方服務(wù)出問(wèn)題后影響自身服務(wù)。 ?

2.以后無(wú)論看到什么類(lèi)型的Future,都要謹(jǐn)慎,因?yàn)檫@玩意說(shuō)的是異步,但是調(diào)用get方法時(shí),他本質(zhì)上是同步等待,所以必須給他設(shè)置個(gè)超時(shí)時(shí)間,否則他啥時(shí)候能返回結(jié)果,就得看天意了!


3.凡是和第三方對(duì)接的東西,都要做最壞的打算,快速失敗的方式很有必要。


4.遇到天大的問(wèn)題,都盡可能保持冷靜,不要亂了陣腳!

接口耗時(shí)2000多秒!我人麻了!的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
临邑县| 东平县| 吉隆县| 元江| 麻栗坡县| 洛浦县| 南昌县| 泉州市| 长武县| 根河市| 伊吾县| 本溪| 石景山区| 正安县| 且末县| 即墨市| 简阳市| 白沙| 陵川县| 道孚县| 南投县| 盐山县| 大渡口区| 玛纳斯县| 乾安县| 宁阳县| 泰州市| 杨浦区| 房产| 时尚| 花垣县| 平原县| 绵竹市| 青川县| 麻城市| 庐江县| 宣武区| 山西省| 循化| 常山县| 达拉特旗|