摘要:那么這么一套保證飛行安全的系統和空難有什么關系呢事實上系統工作得非常好,根據波音自己的統計,系列已經完成了數十萬次的安全起降。
隨著阿里技術的發展,我們的技術系統越來越成為社會的基礎設施,對于這些系統的可靠性要求也就越來越高。但是實際上很多的基礎的產品和系統確仍然會出現一些穩定性問題,那么如何才能構建可靠的系統呢?是不是制定非常嚴格而細致的規則就可以做出可靠的系統呢?
在回答這個問題之前,我們先來看看對于系統可靠性要求非常高的航空業是怎么做的?美國的FAA是在航空安全領域事實上的權威,為了保證航空器的安全,FAA制訂了非常詳細而復雜的航空器認證規則,而這些規則是否就保證了航空器的安全了呢?
讓我們來了解一下最近的兩起空難:
2019年3月10日,埃塞俄比亞航空ET302航班在起飛六分鐘后墜毀,飛機上載有149名乘客和8名機組人員。
2018年10月29日,印尼獅航JT610航班在起飛后約十分鐘墜毀,飛機上載有181名乘客,和8名機組人員。
幾百條鮮活生命的消逝,這是多么嚴重的后果啊!究竟是什么原因導致了這樣的災難呢?
這兩起空難的共同點是都是波音的737MAX機型,并且都是在起飛后不久發生的空難。那么這個背后的原因是什么呢?雖然官方的調查還沒有結束,但是民間的分析指向了同一個原因,那就是這款機型的設計問題。
上圖展示了Boeing 737 MAX的CFM LEAP引擎,值得注意的是和一般民航飛機不同的是,引擎的上沿和機翼平面幾乎齊平。為什么會這么設計呢?這是因為波音737系列最早是上世紀60年代設計的,當時的引擎的直徑小很多,外形更加細長,而機翼的高度是和引擎直徑相匹配的。但是隨著技術的發展,更新更省油的引擎直徑變得越來越大,這時候原來的機翼高度無法滿足更大直徑引擎的安裝空間,要想調整機翼的高度則需要改變起落架的設計,改變起落架的設計則需要改變起落架收起時相關機體位置的設計,而機體設計的變化會帶來更多的變化從而會被FAA認為是一款全新型號的飛機,而全新型號的飛機則需要經歷完整的FAA認證流程,會帶來巨大的時間和經濟成本。為了避免這樣的成本波音選擇了將引擎前移并且提升高度,但是這樣帶來了另外一個問題,由于空氣動力學方面的原因,飛機會變得靜不穩定,特別是在起飛階段,引擎的推力會導致飛機迎角過高進入危險的失速狀態。為了回避這個問題,波音引入了一個自動控制程序MCAS,通過讀取迎角傳感器的數據判斷飛機是否迎角過高,如果過高的話自動控制飛機降低迎角,從而保證飛機的安全。
那么這么一套保證飛行安全的系統和空難有什么關系呢?事實上MCAS系統工作得非常好,根據波音自己的統計,Boeing 737 MAX系列已經完成了數十萬次的安全起降。但是問題在于當傳感器工作不正常時,MCAS有可能會根據錯誤的迎角數據做出錯誤的判斷和動作,也就是在不應該降低迎角的時候降低迎角,導致飛機直沖地面。
回到我們的工作中,前不久我們碰到了一起系統故障,其過程有一定典型的意義,為了描述方面,這里隱去一些具體細節,簡單說一下故障的過程。
開始的時候,由于某些原因導致緩存命中率有所下降,而緩存命中率下降導致了數據庫load升高,而數據庫load升高以及可能的慢SQL導致了部分請求在獲取DB connection的時候超時,從而引發了exception。當exception發生的時候,為了保證系統的可用性,系統邏輯進入了一段兜底邏輯,而這段兜底邏輯在特定的條件下產生了錯誤的返回,從而導致線上臟數據,而這些臟數據帶來了業務資損和大量的人工訂正數據的成本。
這個故障處理的過程并不是重點所以不再贅述,我們要問的是為什么一個簡單的exception會導致這么嚴重的后果呢?
如果我們仔細去觀察上述兩個事例,我們會發現其中有如下幾個共同點:
為了好的目的而引入了非常簡單的備用邏輯直接保證“效果”
這些備用邏輯在絕大部分情況下都能正常工作
但是在極端情況下這樣的邏輯失效了,并且產生了嚴重的后果
換句話說,系統設計者在嘗試用非常簡單的邏輯去解決一個實際上復雜的問題,雖然實際上并沒有完全解決問題,但是因為這樣的邏輯能夠通過大量的測試(或者合規檢查),所以系統設計者“假定”問題得到了解決,從而放心地應用到了生產環境。
那么一個非常復雜的問題是否真的能夠通過一個簡單巧妙的辦法解決嗎?
在系統設計領域,我們通常會把問題的復雜性分為兩類,分別是偶得復雜性,實質復雜性。
偶得復雜性 Accidental Complexity
所謂偶得復雜性是指由開發者自己在嘗試解決問題時引入的復雜性挑戰,一般而言是由解決問題的方法和手段帶來的,對于特定的問題,不同的方法會帶來不同的偶得復雜性。
實質復雜性 Essential Complexity
所謂實質復雜性是由事務本身所決定的,和解決方法無關。
對于偶得復雜性,通過變換解決辦法是有可能用簡單的辦法來解決的,但是對于實質復雜性,我們是無法通過改變手段來解決的,而必須采用相應復雜的方法來解決問題。換句話說對于實質復雜的問題,不要指望有銀彈。
上述事例中,實際的環境和問題是存在比較大的實質復雜性的,然而我們卻試圖通過一些非常簡單的邏輯去解決問題,從而帶來了嚴重的后果。
那么要想防止這類問題,設計高可靠的系統要怎么做呢?
這里我想介紹一條反直覺的軟件設計原則,快速失敗(Fail Fast):
In systems design, a fail-fast system is one which immediately reports at its interface any condition that is likely to indicate a failure.
這是一條反直覺的原則,大部分人聽說這條原則的第一反應是這樣不是讓系統變得更加脆弱了嗎?
實際上并不是,原因在于我們不能停留在某一次的失敗(failure),而是需要觀察完整的過程,如下圖所示:
當問題發生時,系統立即停止工作,由人工介入找到并以合理的方式解決根本的問題,然后系統恢復運作。通過這樣的選擇,我們就能夠更早更容易地暴露問題,每當系統發生問題之后,真正的根因會更快得以解決,所以最后我們就能得到一個更加可靠的系統。
需要說明的是,快速失敗不是說系統設計不處理任何問題到處失敗,而只是在面對essential complexity的時候,不要嘗試用一個簡單粗暴的方案去解決,要么就用一套合理的機制設計去解決它,要么就fail fast把控制權交給系統上層決策,通常來說最終可能會回歸到人,由人來分析和處理問題。
根據實際的工作經驗,我還發現一個有意思的現象,很多系統的設計者往往高估一些能輕易想到的問題的嚴重性,而低估那些想不到的問題的嚴重性。上述的軟件系統故障的例子中,如果異常往外拋出,問題的后果可能僅僅是某些操作人員的部分操作失敗,用戶可能會重試,也可能會開工單把問題反饋上來。只要我們處理工單的同學及時響應并且解決根本問題,這個問題就不會演變成一個比較嚴重的問題。但是不拋出異常通過備用邏輯來兜底一旦失敗,會導致比較嚴重的后果。如果系統的設計者能夠認真衡量和計算這些后果的差別,就會做出更加合理的選擇。
當然還有一點就是快速失敗會把更多數量的問題暴露在用戶面前,讓用戶在心理層面有不好的影響,但是需要注意的是不暴露問題不等于解決問題,暴露問題只是讓大家看到了問題而已。為了更好更早地暴露問題,一方面我們需要引入更完備的測試防止問題進入生產環境,另外一方面也需要引導系統使用者以更加客觀實際的心態來接受系統中的問題。
和構建穩定系統相關的另外一條原則是軟件工程中常說的DRY原則,也就是:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
這一條和穩定系統的關系在于,通過合理的復用設計,能夠大幅度提高系統的可測性,降低調試問題的難度,提高系統的可維護性,背后的邏輯還是比較簡單的,這里不再贅述。
那么要想實踐上述原則構建可靠的系統需要注意哪些方面呢?
結合自己的工作經驗,我認為主要是這么幾個方面:
所有的原則都是有代價的
世界上沒有免費的午餐,借用之前Choice課程老師的一句話,堅持價值觀都是有代價的,我們也可以說
堅持原則都是要付出代價的。
這里的代價包括工作量,短期結果,解決問題的難度,帶來的項目風險等等,系統的設計者需要做出合理的權衡,付出一定的代價才可能應用上述的原則。
刨根問底,5 whys找到根因
當問題發生時,最重要的事情在于找到問題的根因,只有我們解決了根本的問題,系統才會真正變得健壯起來,否則都只是假象。我們可以用?5 whys?的辦法來找到問題的根本原因。
回歸測試保障
個人認為自動化回歸測試相當于汽車的安全帶,我們需要構建覆蓋度高的自動化回歸測試保障體系,從而更早更好地發現問題,減少對于最終用戶的沖擊,把問題扼殺在萌芽狀態。
讓團隊養成好的習慣
不管是一個開發者,還是一個開發團隊,堅持原則并不是臨時起意,而需要成為習慣。只有把原則變成習慣的個人或者團隊,才能夠真正貫徹這些原則。所以平常工作中某些看起來沒有必要的堅持原則,實際上有助于習慣的養成,而當原則成為了團隊的習慣,這些原則才能在需要的時候得以實踐,獲得回報。
不要把fail fast曲解為快速試錯
可能有人會認為fail fast就是快速試錯,也就是不斷嘗試,碰到正確的為止。需要強調的是快速失敗需要很好的設計和機制保證。
以上是我對于構建可靠系統的思考與實踐總結,最近做了一次分享但是感覺沒有講好所以寫下來,歡迎討論和拍磚。
Fail Fast
Software Won"t Fix Boeing"s "Faulty" Airframe
Gregory Travis"s article about Boeing 737 MAX
閱讀原文
本文為云棲社區原創內容,未經允許不得轉載。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11486.html
摘要:阿里巴巴的共享服務理念以及企業級互聯網架構建設的思路,給這些企業帶來了不少新的思路,這也是我最終決定寫這本書的最主要原因。盡在雙阿里巴巴技術演進與超越是迄今唯一由阿里巴巴集團官方出品全面闡述雙八年以來在技術和商業上演進和創新歷程的書籍。 showImg(https://segmentfault.com/img/remote/1460000015386860); 1、大型網站技術架構:核...
摘要:幸運的是,組合易于理解。組件的組合是自然而然的。高效用戶界面可組合的層次結構,因此,組件的組合是一種構建用戶界面的有效的方式。這個原則建議避免重復。只有一個組件符合單一責任原則并且具有合理的封裝時,它是可復用的。 翻譯:劉小夕原文鏈接:https://dmitripavlutin.com/7-... 原文的篇幅非常長,不過內容太過于吸引我,還是忍不住要翻譯出來。此篇文章對編寫可重用和...
摘要:平臺上的微服務架構應用再來看一下我眼中的基于當前最流行的微服務架構的設計是什么樣的,即我們平臺上要運行的典型應用是什么樣的。 showImg(https://segmentfault.com/img/remote/1460000010900878); 8月19日的數人云Container Meetup上,張龍老師做了《基于Kubernetes的PaaS平臺的設計和思考》的精彩分享,分別...
摘要:即使在可用性方面有些小問題也是不可容忍的這意味著可用性必須在多云世界中得到保證。這里的主要機制是將基礎設施分成由硬化邊界包圍的明確界定的區域。企業確保每個決策都有助于基礎設施運營以便為多云做好準備。如今, 多云承諾的未來與企業IT當前的現實背道而馳。這意味著需要改變的不僅僅是對當前體系結構和運營實踐的增量式延續。實際上,企業的業務需要進行整體規劃,因為它們不僅將應用轉移到云端,而且還要為多云...
摘要:持續交付持續交付豆瓣微服務離不開,而核心就是幾點自動化連續小范圍快速可靠。敏捷革命敏捷革命提升個人創造力與企業效率的全新協作模式豆瓣實際上正是敏捷開發的最佳實踐,有了前面的鋪墊,我們可以通過這本書我們來真正了解敏捷開發的全貌。 后端好書閱讀與推薦系列文章: 后端好書閱讀與推薦后端好書閱讀與推薦(續)后端好書閱讀與推薦(續二)后端好書閱讀與推薦(續三)后端好書閱讀與推薦(續四)后端好書...
閱讀 1972·2021-11-25 09:43
閱讀 653·2021-10-11 10:58
閱讀 1730·2019-08-30 15:55
閱讀 1725·2019-08-30 13:13
閱讀 736·2019-08-29 17:01
閱讀 1840·2019-08-29 15:30
閱讀 789·2019-08-29 13:49
閱讀 2172·2019-08-29 12:13