作者 | 位元組跳動基礎架構 / 服務框架團隊研發工程師 - 劉立偉
本文主要介紹了位元組跳動 Sidecar 應用場景,以及進行 Sidecar 大規模版本升級的實踐和總結。
位元組 Sidecar 場景介紹
Sidecar 是一種用於擴展應用程式功能的架構模式。在 Sidecar 架構中,應用程式主進程和一個或多個 Sidecar 進程運行在同一個計算節點中,例如 Pod、物理機等,Sidecar 進程與主進程保持相同的生命周期,為應用程式提供額外的功能支持,例如網絡、安全、日誌、監控等相關功能。
目前,在位元組跳動的微服務架構下,有豐富的 Sidecar 應用場景,包括 Service Mesh、網關、風控、流量錄製、業務安全等幾十種業務場景 Sidecar,支持了抖音、飛書、基礎架構等多個業務線 / 部門。
以下,對幾個典型 Sidecar 應用場景進行介紹。
Service Mesh
在微服務體系下,RPC 框架是微服務之間通信的核心組件,RPC 框架支持了服務發現、流量調度、負載均衡、訪問控制等複雜的服務治理功能。隨著微服務規模變大,RPC 框架暴露出一些問題:
Service Mesh 解決了上述問題,作為服務通信的基礎設施,它實現了一個高性能多協議的數據面代理和一個靈活可擴展的控制面服務,RPC 框架複雜的治理功能下沉到了數據面,數據面以 Sidecar 的形式部署在服務實例中。
相比於傳統的 RPC 框架,Service Mesh 優勢如下:
分布式 API 網關
API 網關(APIGateway)以 API 為核心,提供流量調度、穩定性策略、服務治理等全套解決方案。
API 網關最初的架構是中心化網關,一個網關集群為多個服務進行分流,存在一些痛點問題:
API 網關團隊將網關改造成 Sidecar 部署到服務實例中,實現了分布式網關,並通過 Sidecar 運維平台對分布式網關進行管理。
通過分布式網關方案,解決了上述痛點問題:
除了上述優化,也有其他收益:
風控 Sidecar
風控團隊為業務提供 API 反爬取、反作弊支持,可以降低業務接口風險,加強 API 安全防護。
風控最初提供 SDK 接入方式,用戶接入時,需要在業務代碼中主動集成風控 SDK,存在以下痛點問題:
為解決以上問題,風控團隊和 Service Mesh 團隊合作,藉助 Sidecar 方案和 Service Mesh 的能力,設計開發了風控 Sidecar:
對比風控 SDK,通過風控 Sidecar 的方案,解決了上述痛點問題:
MQ Sidecar
消息隊列 MQ 團隊提供了 RocketMQ/BMQ 兩種消息隊列來處理在線、離線場景。為了滿足業務接入,目前每種消息隊列提供了多個語言的 SDK,存在一些問題:
因此,MQ 團隊引入 Sidecar 架構方案,實現了 MQ Sidecar:
對比 MQ SDK,通過 MQ Sidecar 的方案,解決了上述痛點問題:
Sidecar 架構的優勢和挑戰
優勢
綜合對幾個典型 Sidecar 應用場景的介紹,可以總結出 Sidecar 架構核心優勢如下:
挑戰 - 升級運維
從上述分析可以看出,Sidecar 架構的關鍵是 Sidecar 進程可以獨立運行、單獨升級,因此,只有支持 Sidecar 的升級運維能力,才能使 Sidecar 架構真正發揮出優勢。然而,Sidecar 的升級運維面臨嚴峻的挑戰。
不同於傳統的微服務升級,Sidecar 升級場景更加複雜:
其中最關鍵的特點,Sidecar 升級面向的服務規模很大,以 Service Mesh Sidecar 舉例,生產環境接入情況如下:
在如此大規模的場景下,在進行版本升級的時候,一些問題會被放大:
事故案例介紹
以下是一個真實的事故案例,展示了一次 Service Mesh 升級導致業務故障的處理全過程:
核心問題:穩定性 & 效率
在進行大規模 Sidecar 升級時,最核心的兩個問題是穩定性和效率。
對於穩定性,主要關注業務故障風險:
歷史上,Service Mesh 升級導致過 P0 事故,導致業務受損
歷史上,Service Mesh 升級導致過 P0 事故,導致業務受損
對於效率,主要關注時間、人力成本:
歷史上,Service Mesh 進行 1 次大版本升級,歷時 5 個月,期間多次 feature 插入、問題修復,共發了 25 個小版本才最終完成升級
歷史上,Service Mesh 進行 1 次大版本升級,歷時 5 個月,期間多次 feature 插入、問題修復,共發了 25 個小版本才最終完成升級
Sidecar 大規模升級 - 思考
如何設計一套可靠的 Sidecar 大規模升級方案?為應對穩定性和效率兩個挑戰,主要從變更安全和變更效率兩個角度展開思考:
變更安全
要保障升級過程的安全,必須樹立對風險的正確意識:問題一定存在!
只不過,對於問題,存在已知問題和未知問題,對兩種問題有不同的應對措施:
當然,總有問題不可避免的發生,此時需要積極應對已發生問題:
變更效率
為提升變更效率,首先,要完善變更規範:
其次,通過技術手段,儘量加快升級速度:
總結
綜上,對 Sidecar 大規模升級的思路進行總結:
在不同的升級階段,綜合多種策略保障變更安全和變更效率:
同時,最關鍵的,要將版本升級流程平台化,將上述策略固化在平台上。
Sidecar 大規模升級 - 方案解析
我們構建了一套 Sidecar 運維管理系統,在系統上落地了 Sidecar 大規模升級方案,本節對如何進行安全、高效的 Sidecar 大規模升級進行詳細解析。
運維管理系統
Sidecar 運維管理系統提供了一套 Sidecar 應用運維管理解決方案,支持多種雲環境下 Sidecar 標準化接入、安全運行、觀測運維、版本治理等能力。
系統包含以下核心組件:
方案總覽
以下為完整的升級方案總覽:
方案從升級的各個階段入手,通過引入多項措施控制變更質量,保障變更安全,並在安全的基礎上加速升級,提升變更效率。
在升級前,嚴格控制准入,包括:變更准入、版本准入、服務准入等策略。
在升級中,平台構建了灰度驗證、逐步全量的自動化發布流程,可以謹慎的對版本進行驗證,並且謹慎的將版本逐步全量。
在問題發生時,平台支持通過快速回滾、修復覆蓋的流程,支持快速恢復,快速止損。
在升級後,支持版本治理,包括對長尾版本的收斂,以及在版本發現異常後,對版本進行快速的召回。
另外,在發布的整個流程中:
以下,對升級流程中灰度驗證、逐步全量和異常檢測進行介紹,詳細介紹如何將上述策略落地。
升級流程
灰度驗證
灰度是逐步將新版本驗證穩定、可靠的過程,要在灰度階段儘可能的驗證出問題,不要到全量階段才暴露出問題,不然會導致更大面積的影響。
謹慎驗證
首先,關於灰度覆蓋面,要確保灰度驗證的有效性,需要保證足夠的覆蓋面,這樣才能驗證到足夠多的場景。
但是,如何保證足夠的覆蓋面,對於 Sidecar 新版本可能影響的服務,分為兩類:
比如:新版本變更了負載均衡算法,升級時會明確關注服務的流量負載情況
比如:新版本變更了負載均衡算法,升級時會明確關注服務的流量負載情況
比如:一些歷史邏輯受影響,或者有用戶使用了非公開的特性
比如:一些歷史邏輯受影響,或者有用戶使用了非公開的特性
但是,「預期外受影響的服務」是很難知道的,如果灰度覆蓋不到這些服務,就無法保證灰度的有效性。為了簡單起見,我們選擇了大力出奇蹟的做法,選擇對所有服務進行灰度,這樣就儘量保證了覆蓋面。
其次,關於單服務灰度範圍,位元組的服務部署區分小流量、單機房、全流量的部署階段,小流量階段一般只部署少量的實例,業務升級服務時使用該階段進行新版本驗證,因此 Sidecar 也使用小流量階段進行灰度驗證。
另外,關於升級方式,要保證灰度版本快速生效,這樣有問題才能儘快暴露出來,因此,我們選擇使用熱升級的方式,熱升級後,服務使用的 Sidecar 版本可以立即更新。
最後,還構建了特徵服務機制,Sidecar 的升級,可能會對特定服務產生影響,比如特定語言、框架、通信協議,或者使用了特殊配置的服務,因此,我們構建了特徵集合,並對每種特徵選取有代表性的服務集合,灰度驗證時,首先對這些服務進行驗證,並充分觀察服務是否異常。
比如:Service Mesh HTTP 壓縮算法調整,影響到了配置特殊 HTTP 壓縮算法的服務
比如:Service Mesh HTTP 壓縮算法調整,影響到了配置特殊 HTTP 壓縮算法的服務
防擴散
在灰度階段,要將問題儘早的暴露出來,並防止問題擴散,其中有兩個關鍵點:
為達成防擴散的目標,設計實現了以下方案:
首先,控制升級順序,保障:
具體順序如下:
基於上述升級順序,對全量服務進行順序編排,然後逐步對服務進行灰度升級。
其次,控制升級節奏,要防止一次變更影響過多服務,控制好爆炸半徑:
分批發布:對服務進行合理的批次劃分,確定合適的分批間隔,逐個批次進行升級,目前平台支持指數分批、線性分批策略;
限制變更數量上限:限制好每批的變更數量上限,也限制好每天的變更數量上限。
分批發布 - 指數分批
分批發布 - 線性分批
最後,支持異常檢測、異常阻斷:
檢測到異常後的工單詳情頁面
異常檢測詳情頁面
逐步全量
灰度驗證完成後,說明新版本已經基本穩定,可以開始全量的發布,但是,仍不排除有特殊問題沒有暴露出來,因此,在全量的過程中,也要防範問題的發生。
全量階段,主要目的是進行安全的鋪量,在保證安全的前提下,將新版本逐步的升級到全量服務。
主要採用了以下策略:
不同於灰度階段使用熱升級的方式,使用安全升級進行全量,安全升級不會讓版本立即生效,而是配置好目標版本,跟隨業務升級生效。使用安全升級,可以避免熱升級可能導致的業務流量受損,並且服務在升級時,有服務負責人進行充分的穩定性觀察,相比熱升級安全很多。
和灰度驗證類似,安全鋪量階段,也採用相同的升級順序控制,確保先升級不敏感 / 不重要的服務,保障敏感 / 重要的服務。
和灰度驗證類似,安全鋪量階段,也採用相同的升級節奏控制,進行分批升級,限制變更數量上限,控制好爆炸半徑。
由於升級的區域很多,為加速升級速度,對不同的區域進行合理的並行推進,加快推進速度。
流程總結
對升級流程進行總結,以下為一個升級流程的全貌,包括灰度階段、全量階段,以及,升級完成後的版本收斂階段。
平台將這些流程、策略都固化下來,支持了大規模升級流水線,可以支持自動化的版本升級,保障變更安全,提升變更效率。
以 Service Mesh 升級為例,各階段大概耗時如下:
- 灰度階段 - 線下:5 個工作日
- 灰度階段 - 線上各區域:12 個工作日
- 全量升級(線下 & 線上):11 個工作日
以 Service Mesh 升級為例,各階段大概耗時如下:
異常檢測
在 Sidecar 升級過程中,平台支持主動檢測、主動發現異常,在出現問題後,平台可以及時的阻斷異常,降低故障影響時間,減少業務損失。
Sidecar 升級過程中,如果新版本有問題,一般會導致 Sidecar 自身或者業務出現異常問題,比如:
這些問題一般能從指標、日誌等方面檢測出來,也可以從服務告警反映出異常。因此,我們可以對這些指標、日誌、服務告警等進行檢測,檢測是否有異常發生。
我們和位元組內部上線檢測平台(Niffler)合作,構建了 Sidecar 檢測模型,在升級過程中對服務、Sidecar 的異常進行檢測,檢測模型包含以下三類檢測指標:
落地效果
以 Service Mesh 為例,該大規模升級方案上線後,升級穩定性和效率都有明顯收益:
在穩定性方面,很多問題在灰度驗證時被及時發現,異常檢測機制也檢測、發現到很多異常,版本升級導致的事故數量、等級明顯降低。
在升級效率方面,Service Mesh 發布一次大版本,小版本數量和發布耗時都明顯下降:
Service Mesh 在一個大版本的升級過程中,會發布小版本進行灰度、全量的全流程,如果小版本成功全量到所有服務,則完成大版本的升級。
但是,在小版本發布過程中,如果有緊急 feature、問題修復,則需要重新發布新的小版本,一般要發布多個小版本,才能完成大版本升級。
Service Mesh 在一個大版本的升級過程中,會發布小版本進行灰度、全量的全流程,如果小版本成功全量到所有服務,則完成大版本的升級。
但是,在小版本發布過程中,如果有緊急 feature、問題修復,則需要重新發布新的小版本,一般要發布多個小版本,才能完成大版本升級。
下一步計劃
1. 繼續提升效率
目前,雖然大規模升級效率已經有了明顯提升,但是由於位元組跳動業務覆蓋區域很多,平台缺乏多區域串聯能力,目前操作所有區域的升級仍是一件繁瑣的事情。因此,我們計劃會進一步增強多區域升級的能力,降低多區域操作成本。
另外,為了解決升級過程中,如果發現版本缺陷,進行修復並重新升級,對升級速度影響過大的問題,我們也在探索更高效的小版本自動驗證機制,進一步加快問題發現能力,加快升級速度。
2. 完善異常檢測
目前,雖然支持了異常檢測能力,但是當前的檢測模型還比較簡單,檢測準確率有待提升,存在較多的誤報、漏報。因此,我們後續會對檢測模型進行進一步調優,提升準確率,以發揮異常檢測的更多價值。
3. 加強版本收斂
目前,雖然設計了版本收斂階段,但是平台對於版本收斂的功能支持並不好。有些 Sidecar 仍舊會存在比較多的長尾版本,並且如果出現缺陷版本,召回流程也比較繁瑣。因此,我們後續會進一步加強版本收斂能力,支持更有效的長尾版本收斂、缺陷版本召回功能。
AI 大模型熱潮來襲,看機密計算如何應對敏感數據安全挑戰
號稱比 Python 快 68000 倍的 Mojo 語言正式發布!Rust 能否與之匹敵?
小米一開源項目被批「三無」,項目導師回應;Ruby on Rails之父將Type從Turbo框架中移除 | Q資訊
大模型之戰,騰訊來了