編寫程式碼的 “八榮八恥”:以開關上線為榮,以自信編碼為恥
背景
"我的程式碼太完美了,不可能有bug!" 不知道大家有沒有過這樣的自信。我們團隊的程式碼觀:“是程式碼一定是有bug的。要考慮好充分的兜底以及緊急預案。”
不能將碰運氣當成戰略 --《SRE Google運維解密》
WHAT
編寫程式碼的「八榮八恥」
1. 產品命名:以簡單有趣為榮,以平庸難記為恥。
2. 單個方法:以短小精悍為榮,以冗長費神為恥。
3. 程式碼維護:以持續重構為榮,以停滯不前為恥。
4. 程式設計思想:以面向物件為榮,以面向過程為恥。
5. 程式設計:以開關上線為榮,以自信編碼為恥。
6. 介面定義:以使用者易用為榮,以複雜歧義為恥。
7. 斷言分支:以實時報警為榮,以忽略分支為恥。
8. 報警策略:以定時調整為榮,以放棄維護維持。
WHY
SRE(Site Reliability Engineering站點可靠性工程師)。在《SRE Google運維解密》裡提到世界上第一個SRE,瑪格麗特教授。
瑪格麗特帶著她的小女兒拉夫勞倫一起來到公司,在飛行模擬測試時,拉夫勞倫 偷偷地按下了控制檯上的DSKY鍵。整個模擬程式意外崩潰,發射程式終止。瑪格麗特和組員除錯後發現,拉夫勞倫意外觸發了P01子程式的執行。如果在火箭飛行過程中執行這段程式,後果不堪設想。
瑪格麗特為此提交了一個軟體改動,申請在飛行程式中增加一項特殊狀態檢查避免這個問題。但NASA管理層認為這個錯誤發生的可能性太小,沒有通過。瑪格麗特只能在飛行手冊中新增一段文字:請勿觸發P01程式。
幾天後,阿波羅8飛船執行任務時,宇航員意外觸發了P01程式。幸好瑪格麗特的飛行手冊更新中提到了這種情形,並提供了有效的解決辦法。
無論對一個軟體系統執行原理掌握得多麼徹底,也不能阻止人犯意外錯誤。--瑪格麗特教授
HOW
這裡主要介紹三種開關:版本切換開關、調參配置開關、灰度流量開關。
版本切換開關
新版本上線,上線如果發生問題,一個解決方法是:回滾程式碼。線上服務由多臺機器組成,滾動回滾是需要較長的時間的。一般來說需要幾分鐘到幾十分鐘不等。更有效的方法是在編碼階段對於改動都設定開關。出現問題立即切換到老版本。
穩定性的要務之一:「消除臨時程式碼」。所以一般執行兩週版本確認穩定後要將切換開關及原來的老版本程式碼下線。
開關我們團隊用的是配置管理實現的,開源的有zookeeper的實現。美團用的是OCTO的MtConfig。
調參配置開關
舉一個場景:mysql資料庫經常是被認為非常穩定的基礎設施,甚至有的團隊在做架構設計的時候原則是:訊息中介軟體掛了,我們需要thrift直連降級;快取掛了,我們降級直接走持久層。但是如果mysql掛了,我們就掛。
mysql掛的場景確實不多見,常見的情況是我們自己沒有用好。比如:容量沒有做合理預估。比如建立物理連線時間時長不合理。資料庫連線有一堆引數設定,建議放到配置管理裡去配置。
原因:隨著在線上的執行,QPS升高,不斷加新功能等造成的對資料庫壓力。有可能造成預估或者測算出合理的引數不再合理,為了應對突發問題,建議測算值作為預設值,同時可動態修改配置。
灰度流量開關
大功能上線一般需要灰度,以免不符合預期造成較大損失。一個建議的策略是如果本身QPS較高,那麼可以按照SLA(Service-Level Agreement服務等級協議)可允許的錯誤預算來設定灰度粒度。
比如,系統從年初一直執行良好,沒有出現過問題。這次要上線了。對外承諾SLA3個9。那麼第一次灰度的流量可以按系統0.1%來灰度,那麼就算出現問題了,三天內可以恢復,也可以保證我們的SLA。
總結
不要靠巧合程式設計 --《程式設計師修煉之道》
相關閱讀