作者:十眠
審核&校對:望陶、亦盞
編輯&排版:雯燕
今年雙 11,雲原生中間件完成了開源、自研、商業化三位一體,全面升級到中間件雲產品。MSE 微服務治理通過 Dubbo3.0 支撐了阿里集團核心業務雙 11 的流量洪峰,截止目前集團內 50% 的用戶已經習慣使用 MSE 微服務治理 HSF 和 Dubbo3.0 應用,今天我們來細聊一下 MSE 服務治理專業版中的全鏈路灰度能力,以及它在生產大規模實踐的一些場景。
背景
微服務架構下,有一些需求開發,涉及到微服務調用鏈路上的多個微服務同時發生了改動,需要通過灰度發布方式來更好地控制新版本服務上線的風險和爆炸半徑。通常每個微服務都會有灰度環境或分組來接受灰度流量,我們希望通過進入上游灰度環境的流量,也能進入下游灰度的環境中,確保 1 個請求始終在灰度環境中傳遞,即使這個調用鏈路上有一些微服務沒有灰度環境,這些應用請求下游的時候依然能夠回到灰度環境中。通過 MSE 提供的全鏈路灰度能力,可以在不需要修改任何您的業務代碼的情況下,能夠輕松實現上述能力。
MSE 微服務治理全鏈路灰度特點
全鏈路灰度作為 MSE 服務治理專業版中的拳頭功能,具備以下六大特點
- 可通過定制規則引入精細化流量
除了簡單地按照比例進行流量引入外,我們還支持 Spring Cloud 與 Dubbo 流量按規則引入,Spring Cloud 流量可根據請求的 cookie、header、param 參數或隨機百分比引入流量,Dubbo 流量可按照服務、方法、參數來引入。
- 全鏈路隔離流量泳道
-
通過設置流量規則對所需流量進行“染色”,“染色”流量會路由到灰度機器。
-
灰度流量攜帶灰度標往下游傳遞,形成灰度專屬環境流量泳道,無灰度環境應用會默認選擇未打標的基線環境。
- 端到端的穩定基線環境
未打標的應用屬於基線穩定版本的應用,即穩定的線上環境。當我們將發布對應的灰度版本代碼,然后可以配置規則定向引入特定的線上流量,控制灰度代碼的風險。
- 流量一鍵動態切流
流量規則定制后,可根據需求進行一鍵停啟,增刪改查,實時生效。灰度引流更便捷。
- 低成本接入,基於 Java Agent 技術實現無需修改一行業務代碼
MSE 微服務治理能力基於 Java Agent 字節碼增強的技術實現,無縫支持市面上近 5 年的所有 Spring Cloud 和 Dubbo 的版本,用戶不用改一行代碼就可以使用,不需要改變業務的現有架構,隨時可上可下,沒有綁定。只需開啟 MSE 微服務治理專業版,在線配置,實時生效。
- 具備無損上下線能力,使得發布更加絲滑
應用開啟 MSE 微服務治理后就具備無損上下線能力,大流量下的發布、回滾、擴容、縮容等場景,均能保證流量無損。
大規模生產實踐的場景
本文主要介紹 MSE 微服務治理在支持大客戶過程中總結抽象出來的常用的幾個全鏈路灰度方案生產落地實踐的場景。
場景一:對經過機器的流量進行自動染色,實現全鏈路灰度
-
進入帶 tag 的節點后續調用優先選擇帶有相同 tag 的節點,即對經過 tag 節點的流量進行“染色”。
-
有 tag 的調用鏈路上找不到相同 tag 的節點,則 fallback 到無 tag 的節點。
-
有 tag 的調用鏈路經過無 tag 的節點,如果鏈路后續調用有 tag 的節點,則恢復 tag 調用的模式。
場景二:通過給流量帶上特定的 header 實現全鏈路灰度
客戶端通過在請求中增加制定環境的標識,接入層根據表示進行轉發至表示對應環境的網關,對應環境的網關通過隔離插件調用標識對應的項目隔離環境,請求在業務項目隔離環境中閉環。
場景三:通過自定義路由規則來進行全鏈路灰度
通過在灰度請求中增加指定的 header,且整條調用鏈路會將該 header 透傳下去,只需在對應的應用配置該 header 相關的路由規則,帶指定 header 的灰度請求進入灰度機器,即可按需實現全鏈路流量灰度。
全鏈路灰度的實踐
我們如何快速獲得上述同款全鏈路灰度的能力呢?下面我會帶大家從 0 到 1 快速搭建我們的全鏈路灰度能力。
我們假設應用的架構由 Ingress-nginx 以及后端的微服務架構(Spring Cloud)來組成,后端調用鏈路有 3 跳,購物車(a),交易中心(b),庫存中心(c),他們通過 Nacos 注冊中心做服務發現,客戶端通過客戶端或者是 H5 頁面來訪問后端服務。
前提條件
安裝 Ingress-nginx 組件
訪問容器服務控制台,打開應用目錄,搜索 ack-ingress-nginx ,選擇命名空間 kube-system,點擊創建,安裝完成后,在 kube-system 命名空間中會看到一個 deployment ack-ingress-nginx-default-controller ,表明安裝成功。
$ kubectl get deployment -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
ack-ingress-nginx-default-controller 2/2 2 2 18h
開啟 MSE 微服務治理專業版
-
點擊開通 MSE 微服務治理專業版 以使用全鏈路灰度能力。
-
訪問容器服務控制台,打開應用目錄,搜索 ack-mse-pilot ,點擊創建。
-
在 MSE 服務治理控制台,打開 K8s 集群列表,選擇對應集群,對應命名空間,並打開微服務治理。
部署 Demo 應用程序
將下面的文件保存到 ingress-gray.yaml 中,並執行 kubectl apply -f ingress-gray.yaml 以部署應用,這里我們將要部署 A, B, C 三個應用,每個應用分別部署一個基線版本和一個灰度版本。
# A 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a
name: spring-cloud-a
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# A 應用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-a-new
name: spring-cloud-a-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-a-new
strategy:
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a-new
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
- name: profiler.micro.service.tag.trace.enable
value: "true"
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-a:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-a-new
ports:
- containerPort: 20001
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20001
initialDelaySeconds: 10
periodSeconds: 30
# B 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b
name: spring-cloud-b
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b
strategy:
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-b
labels:
app: spring-cloud-b
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-b
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# B 應用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-b-new
name: spring-cloud-b-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-b-new
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-b
labels:
app: spring-cloud-b-new
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-b:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-b-new
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20002
initialDelaySeconds: 10
periodSeconds: 30
# C 應用 base 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c
name: spring-cloud-c
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c
template:
metadata:
annotations:
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
imagePullPolicy: Always
name: spring-cloud-c
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 30
# C 應用 gray 版本
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: spring-cloud-c-new
name: spring-cloud-c-new
spec:
replicas: 2
selector:
matchLabels:
app: spring-cloud-c-new
template:
metadata:
annotations:
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-c
labels:
app: spring-cloud-c-new
spec:
containers:
- env:
- name: LANG
value: C.UTF-8
- name: JAVA_HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
image: registry.cn-shanghai.aliyuncs.com/yizhan/spring-cloud-c:0.1-SNAPSHOT
imagePullPolicy: IfNotPresent
name: spring-cloud-c-new
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: 250m
memory: 512Mi
livenessProbe:
tcpSocket:
port: 20003
initialDelaySeconds: 10
periodSeconds: 30
# Nacos Server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nacos-server
name: nacos-server
spec:
replicas: 1
selector:
matchLabels:
app: nacos-server
template:
metadata:
labels:
app: nacos-server
spec:
containers:
- env:
- name: MODE
value: standalone
image: nacos/nacos-server:latest
imagePullPolicy: Always
name: nacos-server
resources:
requests:
cpu: 250m
memory: 512Mi
dnsPolicy: ClusterFirst
restartPolicy: Always
# Nacos Server Service 配置
---
apiVersion: v1
kind: Service
metadata:
name: nacos-server
spec:
ports:
- port: 8848
protocol: TCP
targetPort: 8848
selector:
app: nacos-server
type: ClusterIP
動手實踐
場景一:對經過機器的流量進行自動染色,實現全鏈路灰度
有時候,我們可以通過不同的域名來區分線上基線環境和灰度環境,灰度環境有單獨的域名可以配置,假設我們通過訪問 www.gray.com 來請求灰度環境,訪問 www.base.com 走基線環境。
調用鏈路 Ingress-nginx -> A -> B -> C ,其中 A 可以是一個 spring-boot 的應用。
注意:入口應用 A 的 gray 和 A 的 base 環境,需要在 MSE 服務治理控制台打開 A 應用的按照流量比例透傳開關,表示開啟向后透傳當前環境的標簽的功能。這樣, 當 Ingress-nginx 路由 A 的 gray 之后,即使請求中沒有攜帶任何 header,因為開啟了此開關,所以往后調用的時候會自動添加 x-mse-tag:gray 這個 header,其中的 header的值 gray 來自於 A 應用配置的標簽信息。如果原來的請求中帶有 x-mse-tag:gray則會以原來請求中的標簽優先。
針對入口應用 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: http
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a
---
apiVersion: v1
kind: Service
metadata:
name: spring-cloud-a-gray
spec:
ports:
- name: http
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: spring-cloud-a-new
配置入口的 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.com
http:
paths:
- backend:
serviceName: spring-cloud-a-base
servicePort: 20001
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-gray
spec:
rules:
- host: www.gray.com
http:
paths:
- backend:
serviceName: spring-cloud-a-gray
servicePort: 20001
path: /
結果驗證
此時,訪問 www.base.com 路由到 基線環境
curl -H"Host:www.base.com" http://106.14.155.223/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://106.14.155.223/a
Agray[172.18.144.160] -> Bgray[172.18.144.57] -> Cgray[172.18.144.157]
進一步的,如果入口應用 A 沒有灰度環境,訪問到 A 的 base 環境,又需要在 A -> B 的時候進入灰度環境,則可以通過增加一個特殊的 header x-mse-tag 來實現,header 的值是想要去的環境的標簽,例如 gray。
curl -H"Host:www.base.com" -H"x-mse-tag:gray" http://106.14.155.223/a
A[172.18.144.155] -> Bgray[172.18.144.139] -> Cgray[172.18.144.8]
可以看到第一跳,進入了 A 的 base 環境,但是 A->B 的時候又重新回到了灰度環境。
這種使用方式的好處是,配置簡單,只需要在 Ingress 處配置好規則,某個應用需要灰度發布的時候,只需要在灰度環境中部署好應用,灰度流量自然會進入到灰度機器中,如果驗證沒問題,則將灰度的鏡像發布到基線環境中;如果一次變更有多個應用需要灰度發布,則把他們都加入到灰度環境中即可。
最佳實踐
-
給所有灰度環境的應用打上 gray 標,基線環境的應用默認不打標。
-
線上常態化引流 2% 的流量進去灰度環境中
場景二:通過給流量帶上特定的 header 實現全鏈路灰度
有些客戶端沒法改寫域名,希望能訪問 www.demo.com 通過傳入不同的 header 來路由到灰度環境。例如下圖中,通過添加 x-mse-tag:gray 這個 header,來訪問灰度環境。
這個時候 demo 的Ingress 規則如下,注意這里增加了 nginx.ingress.kubernetes.io/canary 相關的多條規則
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-base
spec:
rules:
- host: www.demo.com
http:
paths:
- backend:
serviceName: spring-cloud-a-base
servicePort: 20001
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-gray
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "x-mse-tag"
nginx.ingress.kubernetes.io/canary-by-header-value: "gray"
nginx.ingress.kubernetes.io/canary-weight: "0"
spec:
rules:
- host: www.base.com
http:
paths:
- backend:
serviceName: spring-cloud-a-gray
servicePort: 20001
path: /
結果驗證
此時,訪問 www.demo.com 路由到基線環境
curl -H"Host:www.demo.com" http://106.14.155.223/a
A[172.18.144.155] -> B[172.18.144.56] -> C[172.18.144.156]
如何訪問灰度環境呢?只需要在請求中增加一個header x-mse-tag:gray 即可。
curl -H"Host:www.demo.com" -H"x-mse-tag:gray" http://106.14.155.223/a
Agray[172.18.144.82] -> Bgray[172.18.144.57] -> Cgray[172.18.144.8]
可以看到 Ingress 根據這個header直接路由到了 A 的 gray 環境中。
更進一步
還可以借助 Ingress 實現更復雜的路由,比如客戶端已經帶上了某個header,想要利用現成的 header來實現路由,而不用新增一個 header,例如下圖所示,假設我們想要 x-user-id 為 100 的請求進入灰度環境。
只需要增加下面這 4 條規則:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-base
spec:
rules:
- host: www.demo.com
http:
paths:
- backend:
serviceName: spring-cloud-a-base
servicePort: 20001
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-base-gray
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "x-user-id"
nginx.ingress.kubernetes.io/canary-by-header-value: "100"
nginx.ingress.kubernetes.io/canary-weight: "0"
spec:
rules:
- host: www.demo.com
http:
paths:
- backend:
serviceName: spring-cloud-a-gray
servicePort: 20001
path: /
訪問的時候帶上特殊的 header ,滿足條件進入灰度環境
curl -H"Host:www.demo.com" -H"x-user-id:100" http://106.14.155.223/a
Agray[172.18.144.93] -> Bgray[172.18.144.24] -> Cgray[172.18.144.25]
不滿足條件的請求,進入基線環境:
curl -H"Host:www.demo.com" -H"x-user-id:101" http://106.14.155.223/a
A[172.18.144.91] -> B[172.18.144.22] -> C[172.18.144.95]
相比場景一這樣的好處是,客戶端的域名不變,只需要通過請求來區分。
場景三:通過自定義路由規則來進行全鏈路灰度
有時候我們不想要自動透傳且自動路由,而是希望微服務調用鏈上下游上的每個應用能自定義灰度規則,例如 B 應用希望控制只有滿足自定義規則的請求才會路由到 B 應用這里,而 C 應用有可能希望定義和 B 不同的灰度規則,這時應該如何配置呢,場景參見如下圖:
注意,最好把場景一和二中配置的參數清除掉。
第一步,需要在入口應用 A 處(最好是所有的入口應用都增加該環境變量,包括 gray 和 base) 增加一個環境變量:alicloud.service.header=x-user-id,x-user-id 是需要透傳的 header,它的作用是識別該 header 並做自動透傳。
注意這里不要使用 x-mse-tag, 它是系統默認的一個 header,有特殊的邏輯。
第二步,在中間的 B 應用處,在 MSE 控制台配置標簽路由規則
第三步,在 Ingress 處配置路由規則,這一步參考場景二,並采用如下配置:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: spring-cloud-a-base
spec:
rules:
- host: www.base.com
http:
paths:
- backend:
serviceName: spring-cloud-a-base
servicePort: 20001
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: 'true'
nginx.ingress.kubernetes.io/canary-by-header: x-user-id
nginx.ingress.kubernetes.io/canary-by-header-value: '100'
nginx.ingress.kubernetes.io/canary-weight: '0'
name: spring-cloud-a-gray
spec:
rules:
- host: www.base.com
http:
paths:
- backend:
serviceName: spring-cloud-a-gray
servicePort: 20001
path: /
結果驗證
測試驗證,訪問灰度環境,帶上滿足條件的 header,路由到 B 的灰度環境中。
curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 100"
Agray[192.168.86.42] -> Bgray[192.168.74.4] -> C[192.168.86.33]
訪問灰度環境,帶上不滿足條件的 header,路由到 B 的base環境中。
curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 101"
A[192.168.86.35] -> B[192.168.73.249] -> C[192.168.86.33]
去掉 Ingress Canary 配置,訪問 base A 服務(基線環境入口應用需要加上 alicloud.service.header 環境變量),帶上滿足條件的 header,路由到 B 的灰度環境中。
curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 100"
A[192.168.86.35] -> Bgray[192.168.74.4] -> C[192.168.86.33]
訪問 base 環境,帶上不滿足條件的 header,路由到 B 的 base 環境中。
curl 120.77.215.62/a -H "Host: www.base.com" -H "x-user-id: 101"
A[192.168.86.35] -> B[192.168.73.249] -> C[192.168.86.33]
總結
20 分鍾快速實踐完具有很大技術難度的全鏈路灰度能力,全鏈路灰度其實並不是那么難!
基於 MSE 服務治理的全鏈路灰度能力,我們可以快速落地企業級的全鏈路灰度能力,以上三種場景是我們在生產實踐中大規模落地的標准場景,當然我們可以基於 MSE 服務治理的能力根據自己的業務個性化定制與適配;即使在多種流量來源的背景下,也能做到按照業務定制精准引流。
同時 MSE 服務治理專業版的可觀測性能力使得灰度有效性得到可衡量,灰沒灰到,灰得咋樣,做到“心里有數”。
灰度流量秒級監控
規范發布流程
日常發布中,我們常常會有如下一些錯誤的想法:
-
這次改動的內容比較小,而且上線要求比較急,就不需要測試直接發布上線好了。
-
發布不需要走灰度流程,快速發布上線即可。
-
灰度發布沒有什么用,就是一個流程而已,發布完就直接發布線上,不用等待觀察。
-
雖然灰度發布很重要,但是灰度環境很難搭建,耗時耗力 優先級並不高。
這些想法都可能讓我們進行一次錯誤的發布,不少故障是因為發布直接或間接引起。因此提升發布的質量,減少錯誤的發生,是有效減少線上故障的一個關鍵環節。做到安全的發布,我們需要規范發布的流程。
尾
隨着微服務的流行,越來越多公司使用了微服務框架,微服務以其高內聚、低耦合等特性,提供了更好的容錯性,也更適應業務的快速迭代,為開發人員帶來了很多的便利性。但是隨着業務的發展,微服務拆分越來越復雜,微服務的治理也成了一個比較令人頭疼的問題。
單單拿全鏈路灰度來看,為了保證應用新版本上線前的功能正確性的驗證同時需要兼顧應用發布的效率,如果我們應用的規模很小,我們可以直接通過維護多套環境來保證發布的正確性。但是當我們的業務發展到龐大且復雜程度時,假設我們的系統由 100 個微服務構成,即使測試/灰度環境每個服務占用 1 到 2 個 pod,那么多套環境下來我們需要面臨巨大的成本與運維環境帶來的效率的挑戰。
有沒有更加簡單且高效的方法來解決微服務治理的難題?
MSE 微服務引擎將推出服務治理專業版,提供開箱即用且完整專業的微服務治理解決方案,幫助企業更好地實現微服務治理能力。如果您的系統也可以像本文描述的那樣,快速具備完整的全鏈路灰度能力,並基於該能力進行進一步的微服務治理實踐,不僅可以節省客觀的人力與成本,還可以讓您的企業在微服務領域的探索更加有底氣。
了解更多相關信息,請掃描下方二維碼或搜索微信號(AlibabaCloud888)添加雲原生小助手!獲取更多相關資訊!