搞定微服務線上生命周期管理,同時發布上千個服務節點不是事兒

陳曉猛

2020-06-15

當微服務完成開發、測試后,就可以通過發布服務將其發布到線上。

如果只看一個服務節點的部署,貌似是一項非常簡單的工作,但如果同時發布成百上千個服務節點,尤其是需要在不影響線上業務的前提下完成發布工作,就會變得比較復雜。

批量發布是風險度較高的事情,很大一部分線上事故都是由發布引起的。為了控制風險,需要對發布做足監控,將所有發布步驟在監控大盤上進行實時展示,如果出現發布問題,則應及時告警,并提供完善的回滾功能。

本文選自《微服務治理:體系、架構及實踐》一書。

微服務的部署

▊ 包部署模式

以應用包或服務包的方式進行的部署工作,大部分是在非容器環境的物理機或虛擬機上進行的。如下圖,在多機房情況下,每個機房都會有發布調度服務器,同時軟件版本倉庫在每個機房也都會有相應的鏡像服務。

微服務的包部署模式

1.服務部署包分發

當發布指令從調度中心下發后,每個機房的發布調度服務器會通知本機房內應用服務器集群中的每個服務節點到本機房的軟件版本倉庫下載對應的服務發布包。

這里要注意的是,如果服務節點過多,同時下載微服務的部署包可能會產生瞬時的“網絡風暴”,導致網絡被堵塞。因此,在下載調度上需要做一些優化,讓這些服務節點分批下載,或者控制能同時下載的服務節點的數量。

2.服務狀態檢測

每個服務節點上新的服務部署包下載完成后,就要停止當前運行的服務進程,部署新版本服務。

在停止服務時,由于服務上有正在運行的請求,需要等待這些請求處理完畢,同時不讓新的請求進來,這就是所謂的“優雅停機”??梢酝ㄟ^服務注冊中心將該服務節點直接刪除,或者通過調整該服務節點的路由權重為0來控制不再有新的請求進入該服務節點。另一方面,可以通過一些系統鉤子(如JVM中的shutdownhook)來實現等待所有請求處理完畢再關閉應用的功能,同時做一些資源清理工作。

新版本服務啟動后,會自動到服務注冊中心進行登記注冊,并重新恢復路由權重。這樣,新的請求會重新被路由到該服務節點。

3. 分批發布

微服務的發布如果要做到線上業務無感,就必須控制同時進行上、下線操作的服務節點的數量。因為如果一個服務集群中過多的節點下線,則剩余的節點可能無法負擔當時線上所有的請求流量,所以針對服務發布,必須能控制同時進行上、下線操作的服務節點的數量或比例。

4. 服務發布執行

在上圖中,發布調度服務器承擔了“大腦”的作用,由它提供分批發布策略并向各個服務節點發出發布指令。微服務本身屬于被操作的“物料”,在服務節點上還需要有發布操作的“執行人”。承擔執行人角色的可以是集成在服務節點中的Agent,這個Agent是一個獨立的進程,在服務節點啟動后同步啟動運行,并不斷監聽發布調度服務的指令,收到具體發布指令后,由其執行具體的發布策略。

除了獨立部署的Agent,還可以采用以Ansible為代表的無代理的遠程配置管理工具,以直接通過SSH協議對服務節點進行發布操作管理。使用Ansible的最大好處是,不需要在服務節點上部署Agent程序,減少了Agent帶來的穩定性風險,降低了整體維護成本。

不論是Agent,還是遠程配置管理工具,在服務發布上基本都遵循相似的步驟。

1)檢查環境:檢測系統環境是否正常,相關技術棧是否完備;

2)下載部署包:參考指定軟件版本下載部署物料;

3)關閉服務監控:關閉服務監控,防止部署過程中產生大量報錯信息,但部署監控必須開啟;

4)服務下線:服務注冊中心將該服務節點直接刪除,或者調整該服務節點的路由權重為0來控制不再有新的請求進入該服務節點;

5)停止服務:發出進程關閉信息,通過“優雅停機”的方式在所有存量請求處理完畢之后,關閉服務進程;

6)部署服務:部署新服務的部署包;

7)啟動服務:啟動服務進程;

8)健康檢測:檢測服務是否正常啟動,進程是否正常,并在服務注冊中心中正常注冊;

9)開啟服務監控:服務啟動成功并正常注冊后,開啟服務監控。

▊ 容器化部署模式

在容器編排領域,K8S(Kubernetes)已經成了事實上的王者。本節中,就以K8S為例,討論如何進行P2P直連模式微服務的部署。首先了解K8S的兩個關鍵概念:Pod和Service。

1. Pod

和常規的理解不一樣,K8S管理的基本單元不是容器,而是Pod。Pod是K8S中的最小管理單元,K8S不直接管理容器,就算只有一個容器,也會給它分配一個Pod,Pod里的容器數也可以為0(其實不可能真正為0,因為還有K8S自己創建的基礎容器Pause,它負責網絡及存儲的管理)。

2. Service

可以通過給Pod打標簽(Label)來對Pod進行分類和組織。一個Pod的若干個實例組成一個Service,可以認為Service就是對應一個Pod的副本集群,并通過Service來進行這些副本實例的負載均衡控制。一個Service由一個IP地址和一個Label Selector組成,副本控制器(Replication Controller)通過Label Selector來控制每個Service包含多少個Pod實例。簡單地理解,可以把Service看成一個彈性組。

如果設定一個Pod的實例由基礎容器Pause和一個業務容器組成,并且這個業務容器只運行微服務的某一個服務節點,就可以讓K8S和微服務在“服務”這個概念上達成一致。

微服務和K8S在架構上的映射及融合

上圖中,微服務中的服務對應K8S中的Service,服務節點對應Pod中的業務容器。這樣,只要將每個微服務打包成容器鏡像,并在創建對應Pod資源的時候,將服務名稱以標簽的形式寫入資源清單文件中,就可以利用Label Selector過濾出相關的服務Pod,并通過K8S進行上線、下線、擴容、縮容操作。

▊ 混合部署模式

與服務化類似,大部分企業的容器化之路也不是一蹴而就的。企業內部的IT環境會長期處于新舊混搭的狀態,基礎資源層除了K8S提供的容器服務,可能還存在IaaS云平臺(公有云或私有云),甚至還存在傳統的物理機。整個微服務集群混部在這些不同的環境中,新增加的K8S容器服務平臺需要能與原有的資源平臺共存。

微服務集群的混部

以上架構會導致一個網絡問題,Pod的IP地址只在K8S容器集群里可見,無法和容器集群外的微服務交互,相當于K8S容器集群內、外形成了兩個網絡域。

為了解決這個問題,可以使用第三方開源的網絡組件 Calico,結合物理核心交換機做策略優化,基于BGP協議將容器集群的內、外兩個網絡連接在一起,使得K8S集群外的主機能訪問到Pod的IP地址。它的原理如下。

1)Calico將所有的Node主機變成了路由器,并將該Node主機上存在的所有網段信息都匯報給路由反射器(核心交換機),包括該主機上運行的Pod網絡;

通過BGP網絡解決K8S集群內、外網絡訪問問題

2)配置核心交換機以路由反射器(Route Reflector)的角色與其他節點建立BGP鄰居關系;

3)K8S集群外的主機只要能連接到核心交換機,就可以獲取抵達所有Pod地址的路由信息。

藍綠發布

藍綠發布是一種歷史悠久的服務端應用發布模式,不僅適用于分布式應用或服務,而且也適用于大量的單體應用,它能有效縮短發布導致的業務中斷時間,并且能夠在發布版本出現問題時快速回退。

藍綠發布的核心思想是新舊兩套服務共存。新系統的發布由于不涉及舊系統,自然不需要使用藍綠發布,所以直接發布就行了,只有存量服務的升級才需要使用藍綠發布。所以,準確地說,藍綠發布主要應用于服務的升級。

下面是藍綠發布的示意圖,藍綠發布包含如下幾個步驟。

藍綠發布示意圖

1)部署開始前,線上只有舊版本(藍集群)的服務在運行。

2)在線上部署服務的新版本(綠集群),并在線上進行充分測試。

3)調整路由及負載均衡策略,將流量統一切換到新版本(綠集群),但舊服務(藍集群)不下線。此時兩套集群并存,只是舊集群沒有流量,一旦新版本服務出現異常,通過調整路由及負載均衡策略,快速切換回舊版本(藍集群)。

4)新版本(綠集群)線上穩定運行無異常后,將舊版本服務(藍集群)下線,發布結束。

采用藍綠發布模式,由于新舊兩套服務集群并存,所以一旦發布過程出現異常,回滾速度會比較快,只要切流量即可。但這種發布模式在發布過程中,需要額外占用一套線上資源。

灰度發布

灰度發布是專門針對分布式、多節點的應用或服務的發布方式,和藍綠發布不同,它不需要額外的資源。它利用現有服務集群,通過分批替換的方式將風險控制在可接受范圍內,以減少發布后的質量風險。

灰度發布目前也是互聯網企業的主流發布模式。這些企業一般都構建了完善的灰度發布平臺,利用該平臺,運維人員可以在服務集群中設定發布批次,并同步將用戶(流量)進行劃分,根據功能、兼容性、并發和性能選定發布批次對應的用戶(流量)范圍,分批平滑發布,逐漸擴大范圍,同時將選定的線上用戶路由到新版本上,實時收集用戶反饋來驗證發布效果,以決定是繼續發布還是回滾。下圖就是典型的灰度發布過程,服務節點和用戶流量同步進行階梯切換。

典型的灰度發布過程

在灰度發布的用戶選擇上,除了考慮集群的負載,還可以根據實際需要靈活切分,一般會優先使用用戶區域、用戶級別、用戶設備等屬性。所有選擇都通過灰度發布平臺控制,灰度發布平臺同時要和監控系統緊密結合,以對較長時段的發布過程進行全程監控。

▊ 金絲雀測試

在灰度發布中,第一批(或前N批)發布的服務節點及被切流到該節點上的用戶流量具有特殊意義,它們往往扮演了“先行者”的角色,大部分異常都能在第一批發布中被發現。由于第一批(前N批)發布的范圍非常?。ㄒ话悴怀^1%),影響范圍有限,因此又把第一批(前N批)發布單獨稱為“金絲雀測試”。

“金絲雀測試”的覆蓋范圍很小,所針對的用戶群體可以限制在很小的可控范圍之內。就像筆者目前所負責的在線金融業務,每當一個較大的功能上線時,一般都會先讓部門內部員工承擔“金絲雀”的角色,再將范圍擴大到公司員工,然后基于特定規則(地區、機型、年齡等)挑選一批用戶。

“金絲雀測試”無誤后,就可以進行全量滾動發布了。

小貼士:

礦井工人面臨的一大風險就是井下的瓦斯爆炸,后來人們發現,金絲雀對瓦斯氣體非常敏感,只要空氣中存在極其微量的瓦斯氣體,金絲雀就會停止歌唱或死亡。因此,在采礦設備不發達的古代,礦井工人每次下井都會帶上一只金絲雀,并根據金絲雀的表現來判定是否有瓦斯,以便在危險來臨前及時撤離。

▊ 基于版本號的灰度發布

對服務的升級,會遇到兩種情況。第一種情況是接口不變,只是代碼本身進行完善。這種情況處理起來比較簡單,因為提供給使用者的接口、方法都沒有變,只是內部的服務實現有變化。在這種情況下,采用上述灰度發布的方式驗證后全部發布即可。第二種情況是需要修改原有的接口,如果只是在接口中增加新方法,可以參考第一種情況處理。復雜的是接口方法的參數列表被修改了,這時就需要有相應的手段來區分新舊接口方法,比較通用的辦法是通過增加服務接口的版本號來解決,使用老方法的系統繼續調用原來版本的服務,需要使用新方法的系統則使用新版本的服務。這意味著,在服務框架中,必須通過“服務接口+版本號”的方式來唯一區分服務(在服務多租戶的模式下,還需要加入分組group)?;诎姹咎柕幕叶劝l布升級如下。

基于版本號的灰度發布升級

上圖中,C1代表服務調用方(消費者,Consumer),P1代表服務提供方(提供者,Provider),V1、V2代表版本號。

總體流程是,找一個訪問低谷,先將一部分服務提供方升級為新版本,接著將所有服務調用方升級成新版本,最后將剩余的服務提供方升級成新版本。這個過程涉及流量的各種調整,具體可以參考上圖各個步驟。

讀者評論

相關博文

  • 社區使用反饋專區

    陳曉猛 2016-10-04

    尊敬的博文視點用戶您好: 歡迎您訪問本站,您在本站點訪問過程中遇到任何問題,均可以在本頁留言,我們會根據您的意見和建議,對網站進行不斷的優化和改進,給您帶來更好的訪問體驗! 同時,您被采納的意見和建議,管理員也會贈送您相應的積分...

    陳曉猛 2016-10-04
    3926 645 3 6
  • 迎戰“雙12”!《Unity3D實戰核心技術詳解》獨家預售開啟!

    陳曉猛 2016-12-05

    時隔一周,讓大家時刻掛念的《Unity3D實戰核心技術詳解》終于開放預售啦! 這本書不僅滿足了很多年輕人的學習欲望,并且與實際開發相結合,能夠解決工作中真實遇到的問題。預售期間優惠多多,實在不容錯過! Unity 3D實戰核心技術詳解 ...

    陳曉猛 2016-12-05
    2441 35 0 1
  • czk 2017-07-29
    3483 25 0 1
kof雅典娜赚钱方法中文 15选5杀号精确科学 河南快三形态走势图一定牛河南 mg电子娱乐平台客户端下载 贵州省11选5前三走势 福彩和值谜 贵州快3开奖查询结果 淘股吧股票论坛官网app 山东十一运选五走势图 山东11选5前二遗漏怎么选 南方财富网个股推荐