debug了很久,發(fā)現(xiàn)了Hystrix的兩個(gè)bug

最近基于Hystrix源碼添加一些花邊功能技俐,比如數(shù)據(jù)埋點(diǎn)乘陪、參數(shù)動態(tài)配置等,交付給業(yè)務(wù)之后雕擂,經(jīng)過一系列的壓測之后啡邑,發(fā)現(xiàn)了各種問題。

1井赌、埋點(diǎn)數(shù)據(jù)有問題
2谤逼、熔斷一直不恢復(fù)

先來看下埋點(diǎn)數(shù)據(jù)的問題贵扰,經(jīng)過封裝的Hystrix會把正常請求、試探請求流部、異常請求和熔斷狀態(tài)都記錄下來戚绕,通過壓測后發(fā)現(xiàn)發(fā)生熔斷的時(shí)候,出現(xiàn)了好幾個(gè)數(shù)據(jù)打點(diǎn)枝冀,正常情況下應(yīng)該只有一個(gè)舞丛。通過debug,加日志之后果漾,才發(fā)現(xiàn)這個(gè)隱秘的問題球切。

每次請求都會獲取一個(gè)對應(yīng)的熔斷器,假設(shè)服務(wù)剛啟動的時(shí)候绒障,對應(yīng)的熔斷器還沒有初始化吨凑,這時(shí)每個(gè)線程都會去嘗試初始化一個(gè),通過ConcurrentHashMapputIfAbsent方法保證最后拿到的是同一個(gè)熔斷器端盆,但是作者忽略了一個(gè)問題怀骤,在熔斷器的初始化中费封,有這么一段邏輯:

上述邏輯中焕妙,熔斷器在初始化時(shí),會去注冊Metrics的數(shù)據(jù)流的回調(diào)(本質(zhì)是500ms執(zhí)行一次弓摘,判斷是不是達(dá)到熔斷閾值了)焚鹊。所以,如果有10個(gè)線程同時(shí)初始化熔斷韧献,雖然最終只會使用一個(gè)末患,但是其它9個(gè)熔斷器也會注冊回調(diào)。這就導(dǎo)致了當(dāng)發(fā)生熔斷時(shí)锤窑,熔斷標(biāo)識的埋點(diǎn)數(shù)據(jù)就有問題璧针。

最好的辦法就是初始化熔斷器的時(shí)候,加個(gè)鎖渊啰。

能避免的無效計(jì)算探橱,都盡量的避免。

再來看看第二個(gè)問題绘证,我覺得這算是一個(gè)大bug了隧膏,熔斷一直不恢復(fù),這意味著什么嚷那,意味著錢啊胞枕。

先看看什么情況下,熔斷之后不會恢復(fù)吧魏宽。
熔斷器內(nèi)部有三個(gè)狀態(tài):CLOSED腐泻,HALF_OPEN决乎,OPEN。默認(rèn)情況下派桩,都是處于CLOSED狀態(tài)瑞驱,當(dāng)請求的失敗率過高,達(dá)到閾值時(shí)窄坦,就自動從CLOSED切成OPEN唤反,這是所有的請求會執(zhí)行降級邏輯,這些都沒問題鸭津。熔斷開啟之后彤侍,如果過了一個(gè)試探窗口(5000ms),其中一個(gè)請求線程會把熔斷狀態(tài)從OPEN切成HALF_OPEN逆趋,表明要開始試探下游服務(wù)是不是已經(jīng)恢復(fù)了盏阶。如果下游已經(jīng)恢復(fù),那么這個(gè)請求正常返回之后闻书,會執(zhí)行markSuccess方法名斟,該方法實(shí)現(xiàn)如下:

在這個(gè)方法中,會把熔斷轉(zhuǎn)態(tài)從HALF_OPEN切成CLOSED魄眉,熔斷恢復(fù)砰盐,分析下來,好像這一切是那么的理所當(dāng)然坑律,順理成章岩梳。

但是,但是;卧瘛<街怠!
在熔斷開啟期間宫屠,執(zhí)行降級的請求最后會執(zhí)行一個(gè)叫unsubscribeCommandCleanup的Action列疗,代碼如下:

在該Action中,執(zhí)行circuitBreaker.markNonSuccess()浪蹂,這個(gè)會導(dǎo)致什么問題抵栈?設(shè)想一下,如果試探請求剛把熔斷從OPEN切成HALF_OPEN乌逐,正在等待下游返回時(shí)竭讳,這時(shí)一個(gè)降級請求,理所當(dāng)然執(zhí)行了markNonSuccess浙踢,順帶把熔斷又從HALF_OPEN切成OPEN绢慢,一切都是默默的發(fā)生,不留下一絲痕跡,不加個(gè)日志胰舆,你都不知道發(fā)生了什么骚露。

熔斷狀態(tài)被降級請求切回了OPEN,這時(shí)試探請求結(jié)果成功返回缚窿,執(zhí)行markSuccess方法棘幸,準(zhǔn)備把熔斷從從HALF_OPEN切成CLOSED,殊不知已經(jīng)被內(nèi)部間諜提早偷偷換了轉(zhuǎn)態(tài)倦零,就導(dǎo)致了應(yīng)該恢復(fù)的服務(wù)误续,繼續(xù)降級著,只能祈禱下次沒有降級請求提早偷換狀態(tài)扫茅。

去github上翻了一下蹋嵌,在1.5.12版本中,Action unsubscribeCommandCleanup并不會執(zhí)行 circuitBreaker.markNonSuccess()葫隙,而是在1.5.13中栽烂,為了修復(fù)一個(gè)bug而加入的。

加這段代碼的本意是:Fixed bug where an unsubscription of a command in half-open state leaves circuit permanently open恋脚,就是下面這種寫法腺办。

Observable<Boolean> o = cmd5.observe();
Subscription s = o.subscribe();
s.unsubscribe();

結(jié)果,種下了另一個(gè)隱患糟描,而這個(gè)問題17年7月就被種下了怀喉,遲遲未得到修復(fù),Hystrix難道沒人維護(hù)了蚓挤?

如果想用原生的Hystrix磺送,建議使用1.5.12版本;
如果想用最新的版本灿意,建議對源碼進(jìn)行適當(dāng)?shù)男薷模龠M(jìn)行使用崇呵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缤剧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子域慷,更是在濱河造成了極大的恐慌荒辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件犹褒,死亡現(xiàn)場離奇詭異抵窒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)叠骑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門李皇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宙枷,你說我怎么就攤上這事掉房〖氚希” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵卓囚,是天一觀的道長瘾杭。 經(jīng)常有香客問我,道長哪亿,這世上最難降的妖魔是什么粥烁? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蝇棉,結(jié)果婚禮上页徐,老公的妹妹穿的比我還像新娘。我一直安慰自己银萍,他們只是感情好变勇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贴唇,像睡著了一般搀绣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上戳气,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天链患,我揣著相機(jī)與錄音,去河邊找鬼瓶您。 笑死麻捻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呀袱。 我是一名探鬼主播贸毕,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼夜赵!你這毒婦竟也來了明棍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤寇僧,失蹤者是張志新(化名)和其女友劉穎摊腋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘁傀,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兴蒸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了细办。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橙凳。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痕惋,到底是詐尸還是另有隱情区宇,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布值戳,位于F島的核電站议谷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏堕虹。R本人自食惡果不足惜卧晓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赴捞。 院中可真熱鬧逼裆,春花似錦、人聲如沸赦政。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恢着。三九已至桐愉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掰派,已是汗流浹背从诲。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留靡羡,地道東北人系洛。 一個(gè)月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像略步,于是被迫代替她去往敵國和親描扯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • (git上的源碼:https://gitee.com/rain7564/spring_microservices_...
    sprainkle閱讀 9,336評論 13 33
  • 微服務(wù) 微服務(wù)就是一個(gè)獨(dú)立的可部署的占有自己進(jìn)程的一個(gè)實(shí)體纳像, 我們一般把這個(gè)實(shí)體稱之為服務(wù)荆烈。 微服務(wù)的核心思維和S...
    勇敢的_心_閱讀 1,249評論 1 7
  • 一、前言 在分布式系統(tǒng)架構(gòu)中多個(gè)系統(tǒng)之間通常是通過遠(yuǎn)程RPC調(diào)用進(jìn)行通信竟趾,也就是 A 系統(tǒng)調(diào)用 B 系統(tǒng)服務(wù),B ...
    阿里加多閱讀 22,626評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理宫峦,服務(wù)發(fā)現(xiàn)岔帽,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 開篇 ?對Hystrix耳聞已久导绷,最近剛好想在項(xiàng)目中使用這個(gè)神器就順帶研究了一把犀勒,很多細(xì)節(jié)來不及深入研究只能把宏觀...
    晴天哥_王志閱讀 6,759評論 0 3