編寫代碼的「八榮八恥」- 以開關上線為榮,以自信編碼為恥
背景
"我的代碼太完美了,不可能有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。
總結
不要靠巧合編程 --《程序員修煉之道》
相關閱讀
編寫代碼的「八榮八恥」(上篇)
《程序員修煉之道》解讀
Elasticsearch的基本概念和指標
程序常用的設計技巧
到底多大才算高並發?
美團分布式服務通信框架及服務治理系統OCTO
學會用數據說話-分布式鎖究竟可以多少並發?
大話高可用
編寫代碼的「八榮八恥」- 以開關上線為榮,以自信編碼為恥