本文分享自《華為雲DTSE》第五期開源專刊,作者:聶子雄 華為雲高階工程師、李來 華為雲高階工程師。
微服務是一種用於構建應用的架構方案,可使應用的各個部分既能獨立工作,又能協同配合,微服務的治理模式在適應雲原生的方向也逐步在演進中。本文以汽車行業DMS系統在微服務應用釋出時面臨的挑戰為切入點,介紹了基於微服務SDK框架與JavaAgent技術的全鏈路灰度釋出,整體方案能夠有效提升微服務應用釋出的效率。
1、微服務應用在釋出時面臨的挑戰
微服務架構因其小而獨立的特點受到廣大開發者歡迎,我們生活中很多常見的應用也是基於微服務的架構。微服務架構強調應用拆分為一系列責任單一的小型服務單元,各個服務單元可進行獨立部署,相互協作配合,這種架構模式極大的提高了IT團隊的開發效率。
微服務應用在釋出的時候一般會採用一種叫灰度釋出的策略,它將新版本的軟體逐步地推送給一小部分使用者,以便在全面釋出之前測試和驗證新版本的穩定性和可靠性。這種釋出策略可以減少潛在的風險和影響,因為只有一小部分使用者受到影響,而其他使用者仍然可以使用舊版本的軟體。
常見的灰度釋出一般只針對某個單點的服務進行實施,在很多情況下,這種方法可以大大提高應用釋出的效率及穩定性。當然,單點灰度釋出實際上也存在一些缺點,下面以汽車行業中的DMS系統為例進行分析:
DMS全稱為汽車經銷商管理系統(Dealer Management System),專門為汽車經銷商和售後服務提供商設計的軟體系統,幫助汽車經銷商實現業務數字化、自動化和智慧化,提高業務效率、降低成本、提升服務質量。很多廠商的DMS系統都做過微服務化改造,在提高了團隊開發效率的同時,也遇到了一些業務釋出場景的挑戰:
-
經銷商想在某一個門店A上線自己的新業務,作為業務試點門店,比如新品汽車銷售,或者打折促銷活動等。和新業務相關的流量只會流入試點門店B。
-
為了節約成本以及降低部署服務工作量,希望能夠實現邏輯上的環境隔離。例如,測試環境有部分服務複用生產環境上的模組,開發測試人員只需要聚焦於需要測試的服務模組。
-
經銷商的交易、商品服務有新的業務要上線,新上線的功能間有依賴和互動,要在上線前做一些測試工作。
-
計劃讓測試人員專門賬號來進行現網測試。
-
引入少量比例的生產流量進行驗證。
針對上述問題,一般的思路是透過灰度釋出去解決,透過灰度釋出,可以引入部分的測試流量到新業務模組,也能控制帶有具體特徵的流量只流入到對應的測試模組,其餘流量保持原有方式不動。
但是經過仔細考慮,就會發現如果只做單點灰度釋出,其實是無法完善地解決以上場景的痛點問題,主要體現在:
業務特徵時常只在第一跳,也就是特徵只在入口,傳遞過程中會丟失。
除了第一跳入口,後續微服務之間進行呼叫的時候也會把特徵給丟失。
因此,僅僅依靠單點灰度釋出的能力是不夠的,還需要能夠做到整條微服務呼叫鏈的可灰度,也就是全鏈路灰度的能力,這樣就可以靈活解決類似DMS系統遇到的問題。
後續我們將以全鏈路灰度釋出的場景來展示微服務SDK框架和JavaAgent如何相互結合,解決真實場景中的服務釋出問題。
2、微服務治理方案的選擇
在提出具體解決方案之前,我們可以先了解基於微服務SDK框架以及基於JavaAgent技術的治理模式。微服務SDK進行治理是常見的一種形態,我們常見的Spring Cloud、Dubbo都屬於微服務SDK架構,這種方式通常可以較為方便的透過外部依賴的方式整合各種服務治理功能。JavaAgent則可以透過非侵入的方式引入微服務治理功能,下面將對這兩種模式進行解析。
2.1 基於微服務SDK框架的微服務治理
2.1.1 原理和優勢
服務治理是一個寬泛的概念,通常來說,保證微服務可靠執行的策略,都可以稱為服務治理。這些策略涵蓋開發態、執行態和運維態等微服務生命週期。可以從兩個不同的角度進行描述服務治理:
-
從管理流程上,可以分為進行業務定義和設定治理規則兩個步驟。系統架構師將請求流量根據特徵打上標記,用於區分一個或者一組代表具體含義的業務,然後對這些業務設定治理規則。
-
從處理過程上,可以分為下發配置和應用治理規則兩個步驟。可以透過配置檔案、配置中心、環境變數等常見的配置管理手段下發配置。微服務SDK框架負責讀取配置,解析治理規則,實現治理效果。
-
由於微服務應用是基於微服務SDK框架開發的,開發者可以明顯可以感知微服務SDK框架的存在,此外SDK和應用例項是執行在同一個程序中,這些特點也給微服務的治理帶來了一些好處,包括但不限於以下:
-
更輕量級:微服務SDK框架在執行時不需要起單獨的程序,因此資源開銷較小。
-
治理粒度更精細:微服務SDK可以直接對應用例項的某個方法直接進行管理,因此能夠滿足各種治理場景要求。
-
效能高,時延低:微服務例項之間的鏈路不存在代理,訪問的時候是直接點對點的呼叫,因此時延低,並且微服務SDK框架可以提供高效能的RPC,保障資料的高效傳輸。
華為雲也致力於為開發者提供全面開放,方便高效的微服務SDK框架,目前對外開源的穩定成熟框架主要有Spring Cloud Huawei和Java Chassis。
2.1.2 Spring Cloud Huawei框架
自從Netflix開源出最早的Spring Cloud微服務SDK框架,Spring Cloud在這個領域的發展非常迅速,目前Spring Cloud已經是業界廣泛使用的微服務SDK框架之一。為了讓開發者能夠更加方便、高效地使用Spring Cloud開發可靠的微服務應用,基於Spring Cloud和華為雲服務生態體系,華為雲提供了Spring Cloud Huawei微服務SDK框架,為開發者提供了一站式的開發、部署、運維、監控、治理等全生命週期的服務。
使用Spring Cloud Huawei,開發者可以不用熟悉和了解Spring Cloud,只需要熟悉Spring和Spring Boot,就能夠按照微服務架構模式開發應用。相對於Spring Cloud,Spring Cloud Huawei能夠更好的支援快速微服務開發,提供開箱即用的微服務治理能力。
2.1.3 Java Chassis框架
Java Chassis框架是Apache ServiceComb專案下面向Java語言的微服務框架。ServiceComb專案最早源於華為微服務引擎(CSE),在2017年12月捐贈給Apache基金會,目前已經形成了龐大的微服務生態,而Java Chassis是其中重要一環,著重解決微服務面臨的如下問題:
-
微服務通訊效能
-
微服務運維和治理
-
遺留系統改造
-
配套DevOps
Java Chassis框架包含服務契約、程式設計模型、執行模型與通訊模型四個部分,具備負載均衡、容錯熔斷、限流降級、呼叫鏈追蹤等全面微服務治理能力。下面是總體的架構設計圖:
為了支援軟體工程實踐, Java Chassis 的執行時架構是一個啞鈴結構, 兩端分別是“程式設計模型”和“通訊模型”,中間是“執行模型”。“程式設計模型”面向開發者寫服務介面的習慣,“通訊模型”面向微服務之間的高效編碼和通訊,“執行模型”基於“契約”,提供一種服務無關的插拔機制,能夠讓開發者獨立於業務實現開發治理功能,並且靈活的移除和增加功能,以及調整這些治理功能的處理順序。“執行模型”的核心抽象介面是 Handler ,這個介面是一個非同步的定義,Java Chassis 執行時模型採用純非同步的實現,讓整個系統執行非常高效。
Java Chassis和Spring Cloud都實現了微服務架構模式,相比而言,Java Chassis 是一個更加緊湊的實現,開箱即用,而 Spring Cloud則是相對鬆散的實現,整合了大量的Netflix元件。
2.2 基於JavaAgent的非侵入微服務治理
JavaAgent是如何實現能服務治理能力的?其技術核心在於Java程序啟動時,可以掛載JavaAgent來執行位元組碼的增強邏輯。JVM啟動後,JavaAgent執行於Java應用之前,可以修改原應用的目標類和方法的位元組碼,做到非侵入地增強,原應用中被增強的類在JVM中例項化的物件都是已經被JavaAgent處理過的,因此在業務應用的程式碼執行時,我們的服務治理邏輯就能悄無聲息地透過這種方法實現注入。
例如,我們可以增強服務發現過程,對這一過程中的某個關鍵函式進行攔截增強,插入一段路由篩選服務提供者例項的邏輯,根據服務例項的後設資料和下發的路由規則選定對應的服務提供者,以此來完成灰度釋出的功能。下圖簡化地介紹了位元組碼JavaAgent位元組碼增強的核心原理:
類似地,其他的服務治理能力的開發都可以透過這種方式,使用者的Java業務應用無需修改,業務應用的開發者也無需理解其中的深層原理,只要把實現了服務治理功能的JavaAgent掛載上即可一鍵非侵入接入服務治理。
基於上述原理,華為雲開源團隊開發了無代理服務網格Sermant專案,目前已經在Github開源。Sermant專注於利用Java位元組碼增強技術為宿主應用程式提供服務治理功能,以解決大規模微服務場景中的服務治理問題。Sermant構建了非侵入、高效能、外掛化核心框架,並在框架中提供了對接動態配置中心、事件上報、鏈路標記、心跳等服務治理通用能力。
當前開源倉庫中提供的外掛涵蓋了服務註冊、標籤路由、流量控制、服務監控等常見的服務治理場景。Sermant的後端觀測、動態配置中心、Agent等元件提供的一套完整的解決方案如下:
利用Sermant來進行微服務治理能夠集合上文提到的各種服務架構的優勢:
-
高效能:對比傳統的服務治理邊車,由於沒有邊車程序,因此有更高的效能和更低的資源損耗。
-
非侵入:對比微服務 SDK 架構架構,無需程式碼修改,升級雲原生架構無需程式碼改造。
-
外掛化架構:服務治理功能作為外掛嵌入到JavaAgent內部,可動態部署,且內部充分類隔離,和業務程式碼無類衝突。
3、方案詳解
結合以上兩種治理模式的各自特點,便可設計出理想的全鏈路灰度釋出方案。目前要實現全鏈路灰度,一般要考慮這些問題的處理:
-
在第一跳的地方(一般是閘道器),我們需要能選中各種型別的流量,把這部分流量染色,再路由到正確的目標。
-
除了第一跳,剩下呼叫鏈路中的各個微服務能夠識別染色標,透傳染色標,並路由到正確的目標。
-
能對異常情況進行妥善處理。
3.1 全鏈路灰度釋出方案的具體流程
針對以上問題,我們有一套相對完善的全鏈路灰度釋出方案,整體方案如下:
-
在前端部分,請求會統一攜帶流量標籤引數發到閘道器上面。
-
閘道器會選中各種型別的流量,將這些流量根據需求分別染色,比如透過請求header進行標記染色。
-
閘道器會將染色後的流量轉發到帶有不同tag的後端微服務例項,tag可以由應用釋出流水線注入到相應釋出的微服務例項當中。
-
藉助微服務例項上執行的SDK/JavaAgent,接收到應用閘道器流量的微服務例項會透過SDK/JavaAgent提供的標籤路由能力將流量特徵保留並轉發到合適的下一跳微服務例項。
-
對於後續鏈路上的微服務例項,都可以透過微服務例項上面的SDK/Agent進行特徵的傳遞。
3.2 SDK/JavaAgent如何助力全鏈路灰度釋出?
由於在每個微服務例項都執行著SDK/JavaAgent,因此SDK/JavaAgent可以對每個例項進行細粒度的服務治理,包括限流,熔斷,降級,標籤路由等功能。在全鏈路灰度釋出過程中,對於每條鏈路上的微服務例項,可以藉助SDK/JavaAgent的標籤路由能力實現流量特徵的保留以及傳遞到下一跳微服務例項。進行標籤路由的全流程如下:
3.3 SDK/JavaAgent如何搭配使用?
從上面的方案介紹可以知道無論是SDK還是JavaAgent的方式,其實都可以非常有效地助力全鏈路灰度釋出方案的落地,那遇到具體業務場景對全鏈路灰度釋出有訴求的時候,我們該如何去選擇呢?
對於使用者規劃的新業務,使用者一般會統一技術棧,因此直接使用微服務SDK框架自帶的能力去實現全鏈路灰度釋出會更加方便高效。
對於使用者已有的業務,並且業務內部技術棧也不統一,這時候直接採用非侵入式的JavaAgent去做全鏈路灰度釋出會極大程度地降低改造成本,因為業務程式碼本身不需要做變動,只需要在執行例項上掛載一個JavaAgent即可。當然目前的JavaAgent其實是基於Java 語言的,因此對於別的程式語言,還是得依靠微服務SDK框架來實現全鏈路灰度釋出,但是考慮到目前Java屬於使用量第一的程式語言,因此JavaAgent這種方式基本上還是能夠覆蓋絕大多數的場景。
總的來看,兩種方式其實適用於不同的業務場景,它們之間可以相互補充,形成一整套完善的全鏈路灰度釋出解決方案。
3.4 全鏈路灰度釋出方案帶來的優勢
微服務應用透過全鏈路灰度釋出的方式可以顯著提高發布的效率以及穩定性,關鍵優勢如下:
-
在開發測試過程中,客戶可以根據需求在邏輯上劃分出一套屬於自己的服務鏈路,只需要關注自己設定的特徵流量即可,這種模式可以為客戶省去搭建系統中一些共用的模組時間以及節約環境資源。
-
在釋出過程中,方便地將帶有試點特徵的流量引入到含有自己試點應用的鏈路環境當中。客戶還可以根據需要把一部分生產流量引入到自己的新版本業務鏈路環境當中,完成新版本的驗證。
4、總結
微服務治理架構的形態一直在演進,各種形態有其適用的場景和優缺點。對於企業使用者和開發者來說,如何儘可能以較低的成本、較好的效率來解決微服務治理過程中的各個問題是永恆的目標。
以上我們主要對主流的微服務SDK架構和JavaAgent非侵入治理架構作了解析,對於Java應用場景來說,這兩種治理模式可以在不影響效能的前提解決絕大多數場景的治理問題。
華為雲在微服務治理方向的持續探索也孵化出了Spring Cloud Huawei、Java Chassis、Sermant等優秀的開源專案,並且將持續演進,豐富微服務治理領域的開源生態。
華為開發者空間,匯聚鴻蒙、昇騰、鯤鵬、GaussDB、尤拉等各項根技術的開發資源及工具,致力於為每位開發者提供一臺雲主機、一套開發工具及雲上儲存空間,讓開發者基於華為根生態創新。點選連結,免費領取您的專屬雲主機
點選關注,第一時間瞭解華為雲新鮮技術~