斷路器的回退是被高估的彈性設計 - nurkiewicz

banq發表於2019-07-11

斷路器中的回退是透過一些預先配置的響應來替換髮生的故障,從而使故障的範圍受到限制並且對終端使用者隱藏。然而,在現實生活中,簡單的回退往往過於簡單,我建議採用更強大的方法來處理故障,補償發生的故障。

什麼是斷路器?
斷路器是程式碼和外部依賴關係之間的一層,具有很高的失敗風險。每次呼叫其他服務,資料庫,甚至訪問自己的磁碟時,都有可能出現故障。如果沒有斷路器,這種簡單的錯誤會迅速升級,暴露給終端使用者。通常較小的依賴都會引發龐大的系統故障,導致503 HTTP響應或緩慢。斷路器可快速發現錯誤電平的升高或響應時間延長,它不是減慢整個系統的速度,而是暫時切斷整個依賴,您的程式碼仍然還是失敗了  但是快速地失敗。
快速失敗很重要,在大多數情況下,立即顯示錯誤頁面的網站比在30秒後返回有效響應的網站要好得多。此外,會給你的依賴一些喘息的空間,也許它超載,有一個冷快取或它正在重新啟動。

什麼是回退Fallback?
你的應用程式失敗很快 ,是回退發揮作用的地方。resilience4jHystrix (R.I.P.) 是Java支援的回退斷路器庫。
想法很簡單:當發生異常時,用一些預先配置的響應替換它。它可以是一個恆定值或另一個操作。回退類似:try catch

RecommendedMovies findRecommendations() {
    try {
        return riskyComplexAlgorithm();
    } catch(RuntimeException | TimeoutException e) {
        return bestsellersFallback;
    }
}


想象一下,您正在構建影片流平臺並擁有複雜的機器學習驅動( )演算法,以便找到下一個要觀看的最相關的電影。那麼當我們的演算法中斷時會發生什麼 ?樸素的實現是傳播異常並破壞整個使用者介面,發生503 Internal Server Error。
但我們可以做得更好。我們可以在最近幾天計算觀看次數最多的電影,並將這些未經個性化的推薦回饋給每個人。

回退是天真的
如果沒有準確的推薦,影片流媒體公司或電子商務仍然可以開展業務。他們仍然可以在沒有任何建議的情況下開展業務。
但是,如果業務流程中更重要的一步失敗怎麼辦?例如,您即將向新客戶收取新訂單。這個過程有兩個基本部分:

  1. 欺詐檢測
  2. 信用卡收費

這裡使用斷路器是個好主意:一方面,您不要讓您的客戶永遠等待延遲的失敗。斷路器確保到達超時時間,並嚴格強制執行失敗。另一方面,當斷路開啟時,您可以透過減少負載來為依賴者提供治癒的機會。
但我們可以在這裡應用回退嗎?
破壞欺詐檢測系統的回退基本上是返回一個很簡單的boolean:假設每筆交易都是合法的,則返回真(catch(e) {return true},但是還是可能在一些欺詐性訂單上損失一些錢。當然暫時關閉欺詐檢測聽起來好像不錯,直到你意識到騙子已經發現你竟然沒有欺詐控制機制!

當信用卡支付閘道器的發生問題,回退失敗會很快就出現異常,您無法向客戶的信用卡收費,做了一單買賣但不實際收取任何費用是一種災難。

怎麼辦?

現實生活中的回退
現在,當計算機系統出現故障時,許多企業停止運營。航空公司,證券交易所,甚至醫院或汽車完全依賴於資訊系統。但有些企業過去常常沒有計算機就可以工作,而且技術上可以在沒有它們的情況下執行一段時間:想想收銀員在一張紙上記下您的雜貨,這樣他或她就可以在固定時將它們放回電腦;或者是在沒有電子系統的情況下銷售門票的票務代理。
即使一切都線上,航班也會超額預訂!不知何故,人們學會了如何處理發生故障的機器和最終的一致性。也許我們的系統也應該學習它?

不要回退,試試補償或恢復
再看一下這個欺詐檢測和信用卡支付閘道器發生故障的例子,人類將如何以最誠懇的方式處理這個問題?當欺詐檢測系統發生故障時,人類不會關閉業務,相反,他或她記下所有發生的交易,之後,當欺詐檢測恢復時,有問題的交易將在大批次回顧中進行檢查,商家知道可能只有0.1%的交易是欺詐性的,因此,商家接受該風險,並且當他或她隨後發現欺詐時,立即採取某些行動。

但是,當支付閘道器發生故障時,我們肯定應該停止所有操作嗎?
首先,人們仍然應該被允許瀏覽,搜尋,新增產品到籃子等。如果一個損壞的支付元件破壞了你的整個系統,你就會陷入更深的麻煩。
但是,讓我們再邁出一步。如果我們承擔責任,只需假設所有付款都成功並繼續處理線上購買,該怎麼辦?
如果你在銷售實體商品,這實際上是相當安全的。儘管支付閘道器失敗,假設信用卡已”虛假“地實現了收費,訂單完成了,畢竟,需要幾天或幾個小時你才能發貨,到那時支付閘道器已經恢復,並且您將有機會對整個停機期間使用的所有信用卡進行追溯。客戶甚至不會注意到停電或延誤。
如果有人真的提供假信用卡但我們很樂意接受這樣的購買?不用擔心,很可能其商品包裝仍然沒有離開我們的倉庫,可以立即停止。即使它確實存在並且沒有辦法將其取回,與將商店完全關閉數小時相比,其損失的金錢是大巫見小巫。

如果實現?
在出現故障時,這就是我們應該如何設計我們的系統:

  • 不要讓錯誤立即大範圍傳播爆炸而毀壞整個系統。這會導致無法承受任何故障的脆弱架構
  • 不要認為一切都很好。人們會很快發現您的欺詐檢測系統可以被繞過或從未被執行過。
  • 儘可能做出樂觀的商業決策,但事後要驗證並補償。

從技術角度來看,您的恢復程式碼應該或多或少看起來像這樣:

try {
    businessAsUsual(thingy);
    return true;
} catch(Exception e) {
    scheduleCompensationLater(thingy);
    return true;
}


scheduleCompensationLater()方法應該在持久儲存中記錄失敗的業務事務(banq:類似事件溯源,記錄失敗事件)。稍後,一些後臺流程必須確保我們的樂觀假設是正確的並做出相應的反應。
請記住:
  • 恢復和補償的程式碼也可能失敗。合理的是,如果您的業務流程因儲存故障而失敗,那麼將恢復任務保留在同一儲存中也很可能也會失敗。
  • 否定驗證可能發生得太晚。一旦故障元件重新聯機,您必須快速行動。如果您已經發運了未收費的包裝,那就太晚了
  • 需要對一切進行測量!故障數,恢復時間,待處理恢復任務數。如果數字令人擔憂,請使用kill switch。


kill switch
在某些時候,你會意識到你太樂觀了。交易數量的突然增加可能是一個標誌。只要停電不會持續太長時間,後來保持樂觀和補償是好的。欺詐者會發現並濫用該系統。確保您的系統能夠承受一定程度的故障,但具有自動安全措施。在發現太多可疑活動後,將樂觀的恢復轉變為悲觀的失敗處理方案。

結論
這都是關於風險評估的。我們的父母和祖父母在過去常常沒有電腦控制和協調他們生活的方方面面。這些時代早已不復存在。但如果我們以容忍並可以補償某些錯誤的方式設計我們的系統,我們將設計更強大,更好的使用者體驗。並節省了很多錢。

 

相關文章