服務變更如何做到高可用?

近期,Cloudflare在更新WAF配置規則時,因其中一個規則包含了正則表達式,導致 Cloudflare 全球機器上的 CPU 峯值使用率達到 100%,在最糟糕的時候,流量下降了 82%,對整個互聯網都產生了明顯的影響。

因此,變更的定義,不僅僅是狹義的上線新版本代碼,也應該包含配置變更,數據變更,操作系統變更,網絡變更,基礎設施變更等方面。變更是運維人員的主要工作內容,同時也是導致服務故障的主要原因。據Google SRE統計,線上70%的故障都是由某種變更而觸發的。

服務變更的關鍵點

部署清單

部署清單主要是管理部署期間的整個生命流程,通過將各個階段的各個步驟進行羅列和長期維護,從而逐步形成針對特定變更場景的說明手冊。

如果只是升級一臺服務器的二進制代碼,需要部署清單嗎?答案是肯定的。不能把二進制代碼變更等同於二進制文件替換,在替換動作之外,有很多的工作內容,僅僅是更新完畢以後,就需要考慮如下問題:

  • 程序是否正常啓動

  • 日誌是否存在異常信息

  • 服務功能是否正常

  • 服務性能是否符合預期

  • 服務關鍵指標是否異常

對於多模塊,多系統,多團隊配合的變更操作,如果沒有一份事前經過充分驗證的部署清單,誰在什麼時候應該做什麼事情,准入條件是什麼,交付標準是什麼,有哪些操作禁忌和注意事項,那這種複雜變更的結果就只能靠運氣了。

隨着運維自動化水平的提升,部署清單並不會消失,而是在載體上有所不同,從早期的紙質上線單,到現在內置於部署系統中,實現了更好的經驗傳承,校驗完善,流程管控,信息分享等。

灰度發佈

絕大部分服務,都不應該由單個實例組成。那麼,在變更的時候,就應該避免一次性升級所有實例,而應該分批次的逐步升級,並在每個批次間預留一定的時間間隔對上一批次進行觀察和評估,從而決定是否繼續進行升級,以此來保障變更的質量。

以Google爲例,其灰度發佈的比例,從0.1%開始,每24小時增長10倍推進,從 0.1%-> 1% -> 10% -> 100% (詳見Google SRE中文版162頁),並且灰度的初始比例一定不可以超過服務整體的冗餘度。同時,在對服務進行變更操作的期間,需要將流量摘除,避免對線上產生影響,變更操作完畢後,方可引入灰度流量進行驗證。

在灰度階段,有針對性的選擇灰度流量,儘可能完整的覆蓋各類業務場景和用戶類型,並通過流量調度形成局部熱點,對服務的性能進行驗證,避免全量上線可能出現的性能下降。

快速回滾

變更操作一定要有回滾預案,並能夠快速回滾!日常的變更操作,只要有備份,大多數情況都可以進行回滾。那些無法進行回滾的,一般都是重大變更,這時候,等着你的基本上就是直接在線上調試並修bug以及超長的停機時間和大批的髒數據了。

不同公司對待回滾的態度不同,和其背後的專業能力有很大關係,因此不能盲從。如果對所有的回滾事件不加甄別的進行追責,那麼導致的後果就是對於非核心故障,研發堅決不進行回滾操作導致帶傷上陣,或者說將回滾美其名曰快速迭代。

功能開關

比回滾更高效的方案是功能開關,在發現新功能上線有問題後,可以通過功能開關立即關閉該功能,從而起到更快速的止損效果。可以想象一個場景,一次上線後,發現10個功能裏面有1個功能異常,且引發了部分髒數據,因爲還需要確保其餘9個功能正常,因此不能全併發回滾,只能按照預置的併發度進行回滾,那麼回滾耗時就會較長,這時候,如果有功能開關,那情況就大不一樣了。

線下測試

既然線上有了變更保障能力,那爲啥還要在線下費勁搞集成測試呢,直接在線上測不就行了嗎?我們假設這個觀點是正確的,那麼所有未經測試的代碼全部推送到線上開始灰度,在灰度階段去發現各種問題,然後回滾,修復後繼續上線。但灰度的流量,也是真實的用戶,怎麼能夠拿用戶的真實流量做這樣的事情呢。因此,線下測試還是非常重要的環節,通過線下測試,將80%以上的基本問題攔截在線下環節,在灰度環節,更多的去解決線下環境無法覆蓋的場景。

效果檢查

服務變更後,需要有一系列的基於部署清單管理的效果檢查的內容,例如前面提到的程序是否正常啓動,功能是否正常,性能是否正常,以及本次調整的內容是否符合預期,通過對變更的效果進行驗證,才能最終確認本次變更是否正確。同時,針對服務相關的全局核心指標的監控,在變更期間,既不應該出現異常,更不能被隨意屏蔽掉。

時間窗口

早期,Facebook的交付工程團隊,會在每個工作日進行一次非關鍵性更新,而重大更新則每週進行一次,通常在週二下午進行。這裏就體現了時間窗口的概念,時間窗口主要是用來降低變更導致的影響,常見的時間窗口有如下建議:

儘量避免節前做變更,即使是BAT和運營商,對於全年重要的節假日,往往會提前數週停止業務的非必要性變更,或者是將自動流程轉爲審批流程

儘量避免在業務每天的高峯期做變更,例如很多網絡切割都是選擇凌晨進行操作,就是避免對業務產生影響

儘量避免在下班前尤其是週五下班前做變更,提前通告並全員值守的除外

隔離

如果服務是分組部署(多AZ部署、多Region部署),且分組間能夠做到儘量避免服務間的交互和基礎設施共享,那麼在變更中,就需要利用該特性,對分組進行逐一升級和觀察,避免問題發生擴散,在出現問題的時候,通過流量調度即可快速摘掉流量止損。

通告

任何的變更,都需要事前進行通告,告知相關的上下游團隊,變更時間,變更內容,可能的影響,應急聯繫人等,並在變更期間的各個階段,進行通告。同時,也應該將變更信息錄入到統一的系統中,便於相關上下游訂閱。

服務變更的最佳實踐

藍綠部署

本文以藍綠部署爲基礎,介紹服務變更的最佳實踐。

截圖簡要說明:將系統按照AZ的維度,獨立部署了4組,分別是AZ1、AZ2、Z3和AZ4,這四組完全一致,基於隔離的思路,四個分組間,儘量避免了服務間的交互和基礎設施共享。

考慮到線上環境的複雜度,以及天然存在一定的冗餘度,因此每次僅升級一個AZ分組。在第一個分組AZ1的時候,會進行較爲詳細的驗證,除去常規的自動化檢查外,還會有測試人員的手工效果檢查,以此確保變更的質量。其餘AZ因爲變更內容一致,因此不會有測試人員的接入,僅保留自動化檢查。

如果變更存在問題,因選擇的AZ1是明確小於冗餘度的,因此僅需要摘除流量後,再進行回滾,部分時候,如果研發要求短暫保留現場,也可以滿足其要求。

部署系統

部署系統應該將變更的關鍵點內嵌到部署系統中,不斷完善,讓其成爲變更流程無法逾越的環節,從而更好的保證變更質量。一個部署系統在做好單機部署工作的同時,也應該滿足如下業務側的需求:

  • 提供部署清單功能,並具備自動化的檢查能力,階段性進展通告的能力;

  • 提供版本管理功能,常規變更(二進制代碼和配置)必須全部基於版本庫進行;

  • 提供快速回滾功能,能夠幫助業務快速回滾到上一個穩定版本,並能夠按照業務上下游編排順序進行回滾;

  • 提供時間窗口功能,默認不能夠在業務定義的黑名單時間點上線;

  • 提供備份功能,每次變更都需要將可能影響到的內容進行單機備份,便於快速回滾,默認是需要將上次的發佈包進行全量備份儘量排除掉日誌;

  • 提供灰度發佈功能,能夠定義分組間和分組內的併發度,分組變更的暫停時長等;

  • 提供效果檢查功能,自動化的對業務進行預定義的各類檢查並和部署動作聯動,如暫停變更,繼續變更以及調整灰度的比例;

  • 提供編排功能,滿足多模塊的聯合上線。

配置變更的常見案例

配置文件錯誤

在配置變更的過程中,因配置文件錯誤,導致服務不可用,進而導致全局的服務故障,可能的原因有配置文件被截斷,配置文件合法性校驗缺失導致配置錯誤進程無法啓動,常見的故障:

  • Nginx配置文件錯誤導致網站整體不可用;

  • DNS配置文件錯誤導致網站整體不可用;

  • 基礎服務如數據庫的授權白名單被清空導致多個業務服務異常。

規則衝突

在規則變更的過程中,基於不同業務的規則生效順序不同,新增規則後可能會和原來的一些規則衝突,進而導致業務的異常,常見的場景:

  • Iptables規則,在現有的100條規則中新增1條;

  • Nginx的規則,基於正則匹配的方式進行域名規則的處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章