Netflix通過Peter Alvaro在論文 《路徑驅(qū)動的故障注入(Lineage-driven fault injection)》 中提到了一套名為“Molly”的算法和自身的故障注入測試FIT(failure injection testing)實現(xiàn)了這套安全地自動化故障注入測試。Molly是從一套系統(tǒng)的無故障狀態(tài)出發(fā),然后試圖去回答說“系統(tǒng)是如何達(dá)到目前這種無故障的狀態(tài)的?”簡單舉例介紹一下這個算法的原理。先利用自身的追蹤系統(tǒng)繪制一個樹來表示每個請求經(jīng)過的所有的微服務(wù),假設(shè)如下圖所示:

(A or R or P or B)
在最開始,上圖中的四個節(jié)點都是必須的,且正常的。然后從這個正確輸出反推,隨機選擇一個節(jié)點注入故障,找到并構(gòu)建支持其正確性的邏輯鏈條圖 。當(dāng)節(jié)點注入故障后,這時可能有三種情況:
這個請求失敗,我們已經(jīng)找到一個節(jié)點會故障,從而我們可以刪除未來的實驗中包含這個故障。
這個請示是成功的-但這個失敗的節(jié)點不是關(guān)鍵性的
這個請求成功,有高可用節(jié)點取代了這個失敗
在這個例子中,首先在Ratings中注入失敗,但請求是成功的。說明Rating失敗并不會影響服務(wù)的使用,那就先把這個節(jié)點排除,重新繪制請求樹:

(A or P or B) and (A or P or B or R)
這時可以看到,請求可以通過(A or P or B)的方式實現(xiàn),也可以通過 (A or P or B or R)的方式實現(xiàn)。接下來再在Playlist中注入故障,這時請求還是成功的,因為請求轉(zhuǎn)發(fā)到備用節(jié)點上執(zhí)行,這里將會有一個新的節(jié)點可以訪問。

(A or PF or B) and (A or P or B) and (A or P or B or R)
這時可以更新公式,說明可以通過(A or PF or B) and (A or P or B) and (A or P or B or R)三種方式請求服務(wù)。然后通過這樣不停的測試直到遍歷完所有正確輸出,沒有失敗的節(jié)點可以找到。
Molly沒有規(guī)定怎么搜索空間,所以實現(xiàn)時會估算所有的方案,然后隨機選擇最小的方案的集合。比如,最后的方案可能是[{A}, {PF}, {B}, {P,PF}, {R,A}, {R,B} …]。先選擇所有的單節(jié)點注入失敗,再選擇所的有雙節(jié)點的組合注入失敗,依此類推。
這個測試的目的是在影響大量成員前找到和修復(fù)故障,在生產(chǎn)環(huán)境上進(jìn)行故障測試時,不能接受引起大量的問題節(jié)點。為了避免這個風(fēng)險,只能在指定的范圍構(gòu)建測試,指定的范圍包含兩個關(guān)鍵的概念:故障范圍(failure scope)和注入點(injection points)。故障范圍指的是,把一次故障測試可能產(chǎn)生的影響,限制在一個可控的范圍內(nèi),這個范圍可以小到某個特定的用戶或者設(shè)備,也可以大到所有用戶的1%。而注入點指的是系統(tǒng)內(nèi)計劃會發(fā)生故障的組件,比如RPC層,緩存層,或者持久層。下圖是這個測試的流程示意圖:

故障模擬測試從FIT服務(wù)把故障模擬元數(shù)據(jù)注入到Zuul(緣邊網(wǎng)關(guān)服務(wù))開始,如果請求符合故障范圍(failure scope)則注入失敗。這個故障可能是延遲服務(wù)調(diào)用,或達(dá)到持久層失敗。每個被接觸到的注入點(injection points)檢查這個請求的上下文是否為指定要被注入故障的組件,如果是,在這個注入點模擬故障。