全链路灰度这样做,新需求迭代上线也能放心干饭
作者:泮圣偉(十眠)
概要
?全鏈路灰度是微服務最核心的功能之一,也一直是云上客戶在微服務化深入過程中必須具備的功能。全鏈路灰度因為涉及到的技術、場景眾多,如果云上企業一一自己實現,需要花費大量人力成本對其進行擴展與運維。
涉及到的技術領域
-
?RPC: 微服務之間的路由?
-
- Java 體系涉及 Spring Cloud,Apache Dubbo 主流微服務框架,多語言涉及 Service Mesh?
-
- 端云互聯場景,線上流量 DEBUG。本地通過跳板機將本地服務注冊到注冊中心,希望線上流量滿足路由規則后路由到本地服務對于的實例上再進行 DEBUG,不滿足路由規則的流量路由到線上實例?
-
?MQ?
-
- ?全鏈路壓測場景下,壓測流量發送消息到影子 Topic,壓測流量只訂閱影子 Topic?
-
- ?流量隔離/全鏈路灰度場景下,使用相同 Topic,線上流量訂閱線上消息,隔離流量只訂閱灰度消息?
-
?Database?
-
- ?全鏈路壓測場景下,壓測流量數據落庫到到影子表上?
-
- ?高可用切流的場景下,禁止數據庫操作;單元化下,流量沒有單元標,禁止數據庫操作?
-
?Redis?
-
- ?全鏈路壓測場景下,壓測流量緩存落庫到到影子 KEY 上?
-
- ?高可用切流的場景下,禁止緩存操作;單元化下,流量沒有單元標,禁止緩存操作?
-
?分布式任務調度?
-
- ?對于任務調度,灰度環境提交的任務,被調度到灰度環境的機器上執行?
-
?前端?
-
- ?不同客戶看到的頁面信息不一致?
-
?可觀測性?
-
- ?通過可觀測性監控流量走向,查看流量逃逸情況?
MSE 全鏈路灰度解決方案
?目前 MSE 服務治理專業版提供了完整的產品化的全鏈路灰度解決方案,覆蓋 RPC、MQ、可觀測性等絕大多數場景。只要您的架構是基于 Spring Cloud 或者 Dubbo 框架,您的應用無需升級,無需一行代碼改動,即可玩轉企業級全鏈路灰度功能。?
- ?全鏈路隔離流量泳道?
?1) 通過設置流量規則對所需流量進行’染色’,'染色’流量會路由到灰度機器。?
?2) 灰度流量攜帶灰度標往下游傳遞,形成灰度專屬環境流量泳道,無灰度環境應用會默認選擇未打標的基線環境。?
- ?端到端的穩定基線環境?
?未打標的應用屬于基線穩定版本的應用,即穩定的線上環境。當我們將發布對應的灰度版本代碼,然后可以配置規則定向引入特定的線上流量,控制灰度代碼的風險。?
- ?流量一鍵動態切流?
?流量規則定制后,可根據需求進行一鍵停啟,增刪改查,實時生效。灰度引流更便捷。?
- ?可觀測能力?
?具備泳道級別的單應用可觀測能力
?同時具備全鏈路應用的可觀測能力,可以從全局視角觀察流量是否存在逃逸情況。灰沒灰到,一目了然。
- ?低成本接入,基于 Java Agent 技術實現無需修改一行業務代碼?
?MSE 微服務治理能力基于 Java Agent 字節碼增強的技術實現,無縫支持市面上近5年的所有 Spring Cloud 和 Dubbo 的版本,用戶不用改一行代碼就可以使用,不需要改變業務的現有架構,隨時可上可下,沒有綁定。只需開啟 MSE 微服務治理專業版,在線配置,實時生效。?
- ?具備無損上下線能力,使得發布更加絲滑?
?應用開啟 MSE 微服務治理后就具備無損上下線能力,大流量下的發布、回滾、擴容、縮容等場景,均能保證流量無損。?
如何使用 MSE 全鏈路灰度
?接下來將演示全鏈路灰度的能力,我們使用應用的架構由 Ingress-nginx 以及后端的微服務架構(Spring Cloud)來組成,后端調用鏈路有3跳,購物車(a),交易中心(b),庫存中心(c),客戶端通過 客戶端或者是 H5 頁面來訪問后端服務,他們通過 Nacos 注冊中心做服務發現。?
準備工作
開通 MSE 微服務治理專業版
?登錄 MSE 治理中心控制臺,如果您尚未開通 MSE 微服務治理,請根據提示開通專業版。如果您已經開通了 MSE 微服務治理基礎版,請根據概覽頁中右側的提示,升級到 專業版。?
安裝 Ingress-nginx 組件
部署 Demo 應用程序
?將下面的文件保存到 ingress-gray-demo-deployment-set.yaml 中,并執行?kubectl apply -f ingress-gray-demo-deployment-set.yaml?以部署應用,這里我們將要部署 A, B, C 三個應用,每個應用分別部署一個基線版本和一個灰度版本。?
# A 應用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-a spec:replicas: 2selector:matchLabels:app: spring-cloud-atemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-alabels:app: spring-cloud-aspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-aports:- containerPort: 20001livenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30# A 應用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-a-new spec:replicas: 2selector:matchLabels:app: spring-cloud-a-newstrategy:template:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-alabels:app: spring-cloud-a-newspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-a-newports:- containerPort: 20001livenessProbe:tcpSocket:port: 20001initialDelaySeconds: 10periodSeconds: 30# B 應用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-b spec:replicas: 2selector:matchLabels:app: spring-cloud-bstrategy:template:metadata:annotations:msePilotCreateAppName: spring-cloud-blabels:app: spring-cloud-bspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-bports:- containerPort: 8080livenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30# B 應用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-b-new spec:replicas: 2selector:matchLabels:app: spring-cloud-b-newtemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-blabels:app: spring-cloud-b-newspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-b-newports:- containerPort: 8080livenessProbe:tcpSocket:port: 20002initialDelaySeconds: 10periodSeconds: 30# C 應用 base 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-c spec:replicas: 2selector:matchLabels:app: spring-cloud-ctemplate:metadata:annotations:msePilotCreateAppName: spring-cloud-clabels:app: spring-cloud-cspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOTimagePullPolicy: Alwaysname: spring-cloud-cports:- containerPort: 8080livenessProbe:tcpSocket:port: 20003initialDelaySeconds: 10periodSeconds: 30# C 應用 gray 版本 --- apiVersion: apps/v1 kind: Deployment metadata:name: spring-cloud-c-new spec:replicas: 2selector:matchLabels:app: spring-cloud-c-newtemplate:metadata:annotations:alicloud.service.tag: graymsePilotCreateAppName: spring-cloud-clabels:app: spring-cloud-c-newspec:containers:- env:- name: JAVA_HOMEvalue: /usr/lib/jvm/java-1.8-openjdk/jreimage: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOTimagePullPolicy: IfNotPresentname: spring-cloud-c-newports:- containerPort: 8080livenessProbe:tcpSocket:port: 20003initialDelaySeconds: 10periodSeconds: 30# Nacos Server --- apiVersion: apps/v1 kind: Deployment metadata:name: nacos-server spec:replicas: 1selector:matchLabels:app: nacos-servertemplate:metadata:labels:app: nacos-serverspec:containers:- env:- name: MODEvalue: standaloneimage: nacos/nacos-server:latestimagePullPolicy: Alwaysname: nacos-serverdnsPolicy: ClusterFirstrestartPolicy: Always# Nacos Server Service 配置 --- apiVersion: v1 kind: Service metadata:name: nacos-server spec:ports:- port: 8848protocol: TCPtargetPort: 8848selector:app: nacos-servertype: ClusterIP?針對入口應用 A ,配置兩個 k8s service, spring-cloud-a-base 對應 A 的 base 版本,spring-cloud-a-gray 對應 A 的 gray 版本。?
apiVersion: v1 kind: Service metadata:name: spring-cloud-a-base spec:ports:- name: httpport: 20001protocol: TCPtargetPort: 20001selector:app: spring-cloud-a--- apiVersion: v1 kind: Service metadata:name: spring-cloud-a-gray spec:ports:- name: httpport: 20001protocol: TCPtargetPort: 20001selector:app: spring-cloud-a-new快速構建全鏈路灰度能力
-
?泳道為相同版本應用定義的一套隔離環境。只有滿足了流控路由規則的請求流量才會路由到對應泳道里的打標應用。一個應用可以屬于多個泳道,一個泳道可以包含多個應用,應用和泳道是多對多的關系。?
-
?泳道組:泳道的集合。泳道組的作用主要是為了區分不同團隊或不同場景。?
?登錄?MSE 治理中心控制臺??? [2] ???,找到 ?微服務治理中心 > 全鏈路灰度??
?可以看到我們需要實現上述描述的能力,我們只需要兩個步驟,創建泳道組與創建泳道?
創建泳道組
?點擊創建泳道組按鈕,并選擇我們泳道組涉及到的后端微服務應用,按照上述 demo 來看就是 A, B, C?三個應用?
??
創建泳道
?在?全鏈路灰度?頁面上方選擇創建和泳道組時相同的微服務空間,然后底部單擊?點擊創建第一個分流泳道?。需要注意的是 加入全鏈路流量控制的應用,將不再支持金絲雀發布、標簽路由等功能。?
??
?按照產品的 Step 來,我們分別需要起一個泳道名稱,配置應用標簽,選擇泳道關聯的標簽,去 ACK 控制臺配置 Ingress 的路由規則。?
創建完成的泳道
?查看泳道,分別有兩種模式?
- ?查看模式?
- ?可編輯模式?
入口 Ingress 規則
?配置入口的 Ingress 規則,訪問??www.base.com??路由到 a 應用的 base 版本,訪問??www.gray.com??路由到 a 應用的 gray 版本。?
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: spring-cloud-a-base spec:rules:- host: www.base.comhttp:paths:- backend:serviceName: spring-cloud-a-baseservicePort: 20001path: /--- apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: spring-cloud-a-gray spec:rules:- host: www.gray.comhttp:paths:- backend:serviceName: spring-cloud-a-grayservicePort: 20001path: /驗證特征流量路由到目標應用
?訪問??www.base.com??路由到基線環境?
curl -H"Host:www.base.com" http://{ingress-ip}/a A[172.18.144.155] -> B[172.18.144.120] -> C[172.18.144.79]%?此時,訪問??www.gray.com??路由到灰度環境?
curl -H"Host:www.gray.com" http://{ingress-ip}/a Agray[172.18.144.160] -> Bgray[172.18.144.57] -> Cgray[172.18.144.157]%?在?全鏈路灰度?頁面選擇目標泳道組。在涉及應用中選擇對應的應用,即可出現相應的流量視圖?
?除了查看單個應用的監控圖監控圖外,我們還可以查看泳道組內所有應用的監控圖。通過比對分析所有應用的監控圖,可以分析出更多有用信息。?
- ?可以看出同一時刻,調用的是哪些應用。?
- ?分析流量逃逸問題,判斷逃逸對象。?
總結
?MSE 服務治理的全鏈路灰度產品化能力還在不斷演進,目前我們支持了 MQ、RPC、可觀測等,后續還會支持 XXL-JOB 等更多的場景,目前我們有如何在 MSE 上實現多語言微服務治理?? [3] ??、使用 Cloud Toolkit 實現微服務的端云互聯?? [4] ??、基于 Ingress-nginx 網關實現全鏈路灰度?? [5] ??、基于 MSE 云原生網關實現全鏈路灰度?? [6] ??、基于自建 Spring Cloud Gateway 或 Zuul 網關實現全鏈路灰度?? [7] ??、基于消息隊列 RocketMQ 版實現全鏈路灰度?? [8] ??、通過 Jenkins 構建 CI/CD 實現金絲雀發布?? [9] ??、微服務敏捷開發最佳實踐?? [10] ??等全鏈路灰度相關的完整解決方案,隨著用戶場景與實踐的增多,我們的解決方案還會不斷迭代與豐富。?
典型案例
來電科技
?MSE 服務治理幫助我們系統以很低的成本無侵入的方式快速實現了全鏈路灰度能力,進一步提升了我們系統的穩定性,讓我們新需求的迭代上線更加地安心。?
?-- 來電科技架構師 湯長征?
?來電科技自 2014 年起開始進入共享充電領域,定義并開創了行業,屬于行業內最早的共享充電企業。主要業務覆蓋充電寶自助租賃、定制商場導航機開發、廣告展示設備及廣告傳播等服務。來電科技擁有業內立體化產品線,大中小機柜以及桌面型,目前全國超過 90%的城市實現業務服務落地,注冊用戶超 2 億人,實現全場景用戶需求。?
全鏈路灰度落地
?來電的業務架構如下,最上層是移動端等用戶界面,自建的 Nginx 網關作為接入層,服務層就是各種服務,使用的是 Spring Cloud 與 Dubbo 作為服務框架。?
??
?來電科技全鏈路灰度落地的架構如下:?
?在 Nginx 層配置流量分流的配置,10% 的流量進入灰度環境,90% 的流量進入未打標即線上正式環境,然后經過灰度環境的流量會自動被 MSE 染上對應環境的顏色,從而進行全鏈路的灰度路由,保證流量在灰度環境中閉環,如果沒有灰度環境的機器,比如支付中心只有線上的機器,那么流量會走線上環境,當我們數據中心有存在灰度環境的機器,那么灰度流量還會重新回到數據中心的灰度環境中。?
尾
?MSE 的全鏈路灰度能力隨著客戶場景的深入而不斷擴展與迭代,只有經過客戶打磨的產品才會愈發歷久彌新,歡迎大家嘗鮮體驗。?
相關鏈接
[1] 容器服務控制臺
??https://cs.console.aliyun.com/#/authorize??
[2] MSE 治理中心控制臺
??https://mse.console.aliyun.com/?spm=a2c4g.11186623.2.13.f90a6a60WiEx0N#/auth??
[3] 如何在 MSE 上實現多語言微服務治理
??https://help.aliyun.com/document_detail/184289.html??
[4] 使用 Cloud Toolkit 實現微服務的端云互聯
??https://help.aliyun.com/document_detail/196920.html??
[5] 基于 Ingress-nginx 網關實現全鏈路灰度
??https://help.aliyun.com/document_detail/347790.html??
[6] 基于 MSE 云原生網關實現全鏈路灰度
??https://help.aliyun.com/document_detail/359851.html??
[7] 基于自建 Spring Cloud Gateway 或 Zuul 網關實現全鏈路灰度
??https://help.aliyun.com/document_detail/359858.html??
[8] 基于消息隊列 RocketMQ 版實現全鏈路灰度
??https://help.aliyun.com/document_detail/397318.html??
[9] 通過 Jenkins 構建 CI/CD 實現金絲雀發布
??https://help.aliyun.com/document_detail/384436.html??
[10] 微服務敏捷開發最佳實踐?
??https://help.aliyun.com/document_detail/397319.html??
??點擊文末“????此處?????”,了解更多詳情~??
總結
以上是生活随笔為你收集整理的全链路灰度这样做,新需求迭代上线也能放心干饭的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开发运维效率提升 80%,计算成本下降
- 下一篇: 如何合理使用 CPU 管理策略,提升容器