自愈:問題自動發(fā)現(xiàn)與修復

分享一個頗為曲折的故事肛跌。

一、背景

早在2016年的時候钢猛,我實現(xiàn)了一個監(jiān)控系統(tǒng)伙菜,自動檢查數(shù)據(jù)平臺各節(jié)點的基礎數(shù)據(jù)是否一致。

可是命迈,這個僅僅是監(jiān)控系統(tǒng)贩绕,用于檢驗緩存實時更新功能的正確性。

2019年春節(jié)前夕壶愤,部門提出要做一個萬能的通用的自愈系統(tǒng)淑倾。

當時各種腦暴討論,討論到最后征椒,發(fā)現(xiàn)要做到萬能與通用娇哆,這個自愈系統(tǒng)就需要與業(yè)務無關,也就變成了一個狀態(tài)機模式的調度系統(tǒng)勃救。

而當時周圍還沒有任何一個自愈相關的實踐碍讨,大家不僅希望萬能通用,還希望與業(yè)務有關系剪芥,后來大部分人都有新的項目了垄开,這件事便不了了之了。

年前的時候税肪,我們團隊的服務遇到一個問題溉躲,然后做了一個實實在在的自動發(fā)現(xiàn)與自動修復系統(tǒng),為自動修復積攢了不少經(jīng)驗益兄,下面分享給大家锻梳。

二、幾年后出問題了

image

還是上面的數(shù)據(jù)平臺净捅,基礎數(shù)據(jù)通過內部設計的一套通知機制疑枯,幾乎做到數(shù)據(jù)完全一致。

而對于非基礎數(shù)據(jù)蛔六,比如第三方儲存或服務提供的數(shù)據(jù)荆永,無法走內部這一套通知機制废亭。
這部分數(shù)據(jù)修改后,生效時間會比較久具钥。

為了加速第三方服務的生效時間豆村,第三方服務也復用了內部的通知機制。

但是這樣有一個問題骂删。
緩存服務收到更新通知后掌动,會去第三方服務拉最新數(shù)據(jù),此時第三方服務有很小的概率返回舊數(shù)據(jù)宁玫。

這導致第三方服務數(shù)據(jù)不一致問題小概率性出現(xiàn)粗恢。

……

巧妙的是,以前底層cms的很多計算邏輯都是通過各種腳本定時完成的欧瘪。
這使得每計算一個數(shù)據(jù)眷射,都會觸發(fā)一次寫操作。

這種多次寫恰好修復了這個不一致問題恋追。

因為第一次寫的時候凭迹,第三方服務會有小概率計算出舊數(shù)據(jù)。
幾秒后第二次寫的時候苦囱,第三方服務依賴的下游是舊數(shù)據(jù)的概率就非常小了嗅绸。
實際情況時,會寫很多很多次撕彤,所以概率被無限縮小鱼鸠。

PS:對于后面的重復寫,大家可以理解為第三方服務計算的新數(shù)據(jù)沒變化羹铅,但是緩存認為有變化蚀狰,再次去拉取第三方服務。

就這樣第三方服務運行了好幾年职员,幾乎沒出現(xiàn)什么問題麻蹋。

……

不幸的是,春節(jié)的前幾周焊切,底層cms升級改造正式上線扮授,所有計算邏輯只會寫一次。

這使得第三方服務問題暴露出來专肪,被無數(shù)運營投訴刹勃。

讓底層cms暫時回滾是行不通的。
對數(shù)據(jù)系統(tǒng)的架構進行重構嚎尤,使這個第三方服務支持快速更新荔仁,短期內也沒那個時間。
所以做一個自愈系統(tǒng)就顯得非常有必要了。

三乏梁、自愈系統(tǒng)架構

簡單思考下次洼,自愈系統(tǒng)大概分為三大模塊:數(shù)據(jù)輸入模塊、數(shù)據(jù)拉取模塊掌呜、數(shù)據(jù)對比修復模塊滓玖。

如下圖

image

數(shù)據(jù)輸入模塊一般是從消息隊列接收消息。
這里可能還需要對輸入的數(shù)據(jù)進行過濾质蕉、標準化等預處理邏輯。
最終將需要監(jiān)控的數(shù)據(jù)放入任務隊列翩肌。

由于不同任務需要等待不同的時間才能啟動檢查模暗。
任務隊列可以是一個按處理時間排序的列表。

數(shù)據(jù)拉取模塊每次從任務隊列頂部檢查是否有到達時間的任務念祭。
有了取出兑宇,先拉取基準數(shù)據(jù)(認為是正確的),再拉待校驗的數(shù)據(jù)(可能需要拉很多接口的數(shù)據(jù))粱坤。
當然隶糕,這里與數(shù)據(jù)輸入一樣,需要對拉取的結果進行過濾與標準化站玄。

之后就是對比數(shù)據(jù)是否一致枚驻,不一致了調用修復接口進行修復。

上面就是一個自愈系統(tǒng)簡化后的模型株旷。

四再登、加強版自愈

年前的時候,讓一個同事做了這樣一個系統(tǒng)晾剖。

那個版本為了快速測試流程锉矢,很多參數(shù)是 hardcode 的。
我簡單的 codeview 了架構流程齿尽,看著沒啥問題沽损。

后面我提出一個要求:這些參數(shù)需要配置化。
于是相關參數(shù)被改成配置文件讀取后循头,就直接發(fā)布上線了绵估。

上線后的一個月內,運營也都沒有來反饋問題了贷岸。

……

可是壹士,半個月前,運營突然又大面積反饋這個問題了偿警。

我心中有一個很大的疑惑躏救。
如果自愈系統(tǒng)有問題,一個月前就應該不斷的遇到問題。
如果自愈系統(tǒng)沒問題盒使,這些問題就應該被自動發(fā)現(xiàn)自動修復崩掘。
難道僅僅是概率問題?

于是我同時要到 自愈系統(tǒng)和 第三方系統(tǒng)的代碼少办,進行 codereview苞慢。
然后發(fā)現(xiàn)第三方系統(tǒng)存在兩個問題,自愈系統(tǒng)存在一個過濾問題英妓。

將問題反饋給相關負責人后挽放,第三方系統(tǒng)的問題被修復了一個,自愈系統(tǒng)的過濾問題也被修復了蔓纠。

但是運營依舊在投訴辑畦,這說明問題依舊存在。

此時腿倚,我們正處于組織架構調整期纯出。
第三方系統(tǒng) 和 自愈系統(tǒng)的負責人都去做其他新項目去了。

問題還是需要解決敷燎,于是我開始接手這兩個服務了暂筝。

……

接手后需要做兩件事情。

第一件事是修復第三方系統(tǒng)遺留的那個已知問題硬贯。
第二件事是分析自愈系統(tǒng)為啥沒有發(fā)現(xiàn)問題焕襟、修復問題。

由于數(shù)據(jù)節(jié)點眾多澄成,目前自愈系統(tǒng)檢查節(jié)點數(shù)據(jù)的邏輯是抽樣拉取的胧洒。
分析了之前有問題的數(shù)據(jù),如果數(shù)據(jù)有問題墨状,是必現(xiàn)的卫漫。

難道剛開始那幾秒,數(shù)據(jù)在反復變化肾砂?
于是我猜想列赎,一次抽樣可能發(fā)現(xiàn)不了問題,全部計算量又太大镐确。

一種不錯的方法是有策略的多次檢查包吝。

最常見的策略有:等差策略、指數(shù)策略源葫。

等差策略就是每隔多少秒觸發(fā)一次檢查诗越。
比如第5、10息堂、15嚷狞、20块促、25、30秒檢查床未。

指數(shù)策略就是每次間隔時間翻倍竭翠。
比如第5、10薇搁、20斋扰、40、80啃洋、160秒檢查传货。

我對這兩個策略都不是很滿意,因為時間間隔的太近了宏娄。

于是我引入了階乘策略损离,即相乘的因子每次加一。
比如第5绝编、10、30貌踏、120十饥、600、3600秒檢查祖乳。

算法確定后逗堵,就是代碼實現(xiàn)了。

將算法封裝在一個對象內后眷昆,實現(xiàn)還算簡單蜒秤,很快我就上線了。

image

當我分析策略的正確性時亚斋,我驚呆了作媚。
數(shù)據(jù)拉取模塊竟然有一個隱藏很深的BUG,使得結果永遠都被認為是一致的帅刊。

自此纸泡,我前面提到的疑惑算是得到了解釋,確實是概率問題赖瞒。自愈系統(tǒng)從來沒正常執(zhí)行過女揭。

問題修復后,運營果然幾乎不反饋問題了栏饮。
后來他們又反饋了一個問題吧兔,分析之后,發(fā)現(xiàn)是新功能不在監(jiān)控范圍之內袍嬉,我補充進去后境蔼,然后到現(xiàn)在為止再也沒收到反饋了。

五、回顧

回顧一下這個自愈系統(tǒng)欧穴,整個流程大概確定了民逼。

大概如下:

1、MQ 輸入任務涮帘、過濾拼苍、標準化
2、有策略的進入任務隊列
3调缨、調度任務拉取基準數(shù)據(jù)與對比數(shù)據(jù)疮鲫,結果標準化
4、任務結果對比弦叶,不一致時進行自愈修復

疑惑解開之前俊犯,我引入了有策略的多輪檢查機制來確保問題被發(fā)現(xiàn)與修復。

而最終的問題竟然是一個隱藏的BUG伤哺。

這個問題屬于邏輯BUG燕侠,只能引入單元測試來發(fā)現(xiàn)。

由于涉及到各種接口網(wǎng)絡調用立莉,還需要使用 MOCK 鉤子來解決依賴绢彤。

單元測試和MOCK鉤子我在個別項目中用到過,后面有時間了蜓耻,也引入到這個項目來茫舶。

到時候再給大家分享一下單元測試的實踐與MOCK鉤子的實踐。

《完》

-EOF-

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末刹淌,一起剝皮案震驚了整個濱河市饶氏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌有勾,老刑警劉巖疹启,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柠衅,居然都是意外死亡皮仁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門菲宴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贷祈,“玉大人,你說我怎么就攤上這事喝峦∈铺埽” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵谣蠢,是天一觀的道長粟耻。 經(jīng)常有香客問我查近,道長掂摔,這世上最難降的妖魔是什么撤逢? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任塌忽,我火速辦了婚禮宁改,結果婚禮上,老公的妹妹穿的比我還像新娘秃症。我一直安慰自己南片,他們只是感情好眼滤,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布赏僧。 她就那樣靜靜地躺著大猛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淀零。 梳的紋絲不亂的頭發(fā)上挽绩,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音驾中,去河邊找鬼唉堪。 笑死,一個胖子當著我的面吹牛肩民,可吹牛的內容都是我干的巨坊。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼此改,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了侄柔?” 一聲冷哼從身側響起共啃,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎暂题,沒想到半個月后移剪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡薪者,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年纵苛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片言津。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡攻人,死狀恐怖,靈堂內的尸體忽然破棺而出悬槽,到底是詐尸還是另有隱情怀吻,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布初婆,位于F島的核電站蓬坡,受9級特大地震影響猿棉,放射性物質發(fā)生泄漏。R本人自食惡果不足惜屑咳,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一萨赁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兆龙,春花似錦杖爽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坝橡,卻和暖如春泻帮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背计寇。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工锣杂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人番宁。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓元莫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝶押。 傳聞我的和親對象是個殘疾皇子踱蠢,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容