Spring Cloud Gateway和Zuul是兩種常用的微服務架構中的API Gateway,它們均能實現路由轉寄和過濾器處理等功能。通過配置路由規則,可以將請求路由到灰階環境中,對灰階版本進行驗證和測試。藉助MSE提供的全鏈路灰階能力,您無需修改業務代碼,即可實現端到端的全鏈路流量控制。本文介紹如何通過配置Spring Cloud Gateway或者Zuul網關實現全鏈路灰階。
前提條件
背景資訊
本文通過類比真實的調用鏈路為您示範MSE全鏈路灰階功能。您無需修改任何業務代碼,只需要給入口應用設定流量規則,該流量的標籤會通過鏈路透傳到下一個灰階版本中。在每個應用的調用過程中,符合金絲雀條件的流量會優先調用對應的版本,如果沒有對應版本則會自動切換回基準版本(即穩定版本)。
部署spring-cloud-gateway、spring-cloud-a、spring-cloud-b、spring-cloud-c這四個業務應用,以及註冊中心Nacos Server。調用鏈路為:spring-cloud-gateway->A->B->C。
應用之間的調用既包含了Spring Cloud服務調用,也包含了Dubbo服務調用。
全鏈路灰階提供了給流量染色,並讓灰階流量優先調用灰階節點的能力,協助您進行可控的灰階驗證,保障穩定性。
全鏈路灰階驗證通常採用以下策略:
直接調用現有線上流量的一小部分進行測試,通常按照百分比控制。
按照特定規則篩選線上流量進行驗證,如使用指定的Header或Cookie等。
本文將分別介紹上述兩種策略配置方式,以便適應微服務架構中不同的灰階發布需求。
步驟一:將應用接入MSE微服務治理
將ACK微服務應用接入MSE治理中心,您可以選擇您需要的方式實現應用接入。更多資訊,請參見ACK微服務應用接入MSE治理中心。
為ACK命名空間中的應用開啟MSE微服務治理
登入MSE治理中心控制台,並在頂部功能表列選擇地區。
在左側導覽列,選擇治理中心 > 应用治理。
在应用列表頁面,單擊ACK应用接入。
在ACK应用接入對話方塊中,進行配置,配置完成後,單擊确定。

配置項
說明
集群类型
選擇ACK集群、ACK Serverless集群或ACS集群。
說明如果您尚未授權Container Service調用微服務引擎,則需要單擊請授權進行授權。
集群名称/ID
選擇接入MSE微服務治理的集群名称/ID,可通過關鍵詞搜尋。
ack-onepilot
顯示ack-onepilot接入狀態,關於ack-onepilot組件介紹和升級MSE微服務治理組件可參見ack-onepilot組件和安裝和升級MSE微服務治理組件。
如果您未安裝ack-onepilot,以ACK叢集為例,選擇後系統將自動開始安裝,並顯示“安裝過程大概需要1分鐘,請稍後”。
如果您使用子帳號接入,提示沒有許可權使用時,您可以登入Container Service管理主控台進入目的地組群,然後單擊組件管理,找到ack-onepilot並單擊安裝。
如果您已安裝ack-onepilot,介面會顯示“已安裝+ack-onepilot版本號碼”,例如已安裝4.2.0版本。
說明該步驟接入的組件為ack-onepilot,您可以登入Container Service管理主控台進入目的地組群,然後單擊營運管理 > 組件管理查看詳情。
ack-onepilot安裝後會自動注入探針,可能會導致應用啟動耗時增加(10s內)。
通過命名空間方式接入,如果目的地組群所在的Region不在以下範圍內,請確保叢集能夠訪問公網且能夠連通acm.aliyun.com:8080:青島、杭州、北京、上海、上海-金融雲、深圳、中國香港、新加坡、法蘭克福、雪梨、矽谷、維吉尼亞。
接入类型
選擇命名空间接入。
容器集群命名空间
選擇容器集群命名空间。
治理命名空间
選擇治理命名空间。
為單個應用開啟MSE微服務治理
登入MSE治理中心控制台,並在頂部功能表列選擇地區。
在左側導覽列,選擇治理中心 > 应用治理。
在应用列表頁面,單擊ACK应用接入。
在ACK应用接入對話方塊中,進行配置,配置完成後,單擊确定。

配置項
說明
集群类型
選擇ACK集群、ACK Serverless集群或ACS集群。
說明如果您尚未授權Container Service調用微服務引擎,則需要單擊請授權進行授權。
集群名称/ID
選擇接入MSE微服務治理的集群名称/ID,可通過關鍵詞搜尋。
ack-onepilot
顯示ack-onepilot接入狀態,關於ack-onepilot組件介紹和升級MSE微服務治理組件可參見ack-onepilot組件和安裝和升級MSE微服務治理組件。
如果您未安裝ack-onepilot,以ACK叢集為例,選擇後系統將自動開始安裝,並顯示“安裝過程大概需要1分鐘,請稍後”。
如果您使用子帳號接入,提示沒有許可權使用時,您可以登入Container Service管理主控台進入目的地組群,然後單擊組件管理,找到ack-onepilot並單擊安裝。
如果您已安裝ack-onepilot,介面會顯示“已安裝+ack-onepilot版本號碼”,例如已安裝4.2.0版本。
說明該步驟接入的組件為ack-onepilot,您可以登入Container Service管理主控台進入目的地組群,然後單擊營運管理 > 組件管理查看詳情。
ack-onepilot安裝後會自動注入探針,可能會導致應用啟動耗時增加(10s內)。
通過命名空間方式接入,如果目的地組群所在的Region不在以下範圍內,請確保叢集能夠訪問公網且能夠連通acm.aliyun.com:8080:青島、杭州、北京、上海、上海-金融雲、深圳、中國香港、新加坡、法蘭克福、雪梨、矽谷、維吉尼亞。
接入类型
選擇单个应用接入。
接入步骤
按照接入步驟進行操作。
Step 1:進入叢集工作負載-無狀態應用頁面,切換到應用的命名空間下。
Step 2:找到所接入的應用,點擊「查看Yaml」。
Step 3:按以下格式編輯Labels,完成後點擊「更新」。
spec: template: metadata: labels: # 填寫“on”表示開啟接入,需加上雙引號 msePilotAutoEnable: "on" # 填寫接入到的治理命名空間,值不存在可自動建立 mseNamespace: default # 填寫接入MSE的實際應用程式名稱,需加上雙引號 msePilotCreateAppName: "your-deployment-name"
步驟二:部署應用(類比線上情境)
登入Container Service管理主控台,在左側導覽列選擇叢集列表。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇。
在無狀態頁面選擇命名空間,然後單擊使用YAML建立資源。
本文樣本中部署一個註冊中心Nacos Server,然後部署spring-cloud-gateway、spring-cloud-a、spring-cloud-b、spring-cloud-c這四個業務應用。您也可以直接在Demo中擷取對應的源碼。
註冊中心Nacos Server YAML
spring-cloud-c應用YAML
spring-cloud-b應用YAML
spring-cloud-a應用YAML
spring-cloud-gateway應用YAML
執行以下命令查看部署結果:
kubectl get svc,deploy預期輸出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 172.16.x.x <none> 443/TCP 23h service/nacos-server ClusterIP 172.16.x.x <none> 8848/TCP,9848/TCP 94s service/spring-cloud-gateway-slb LoadBalancer 172.16.x.x 8.130.x.x 80:32641/TCP 57s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nacos-server 1/1 1 1 94s deployment.apps/spring-cloud-a 1/1 1 1 66s deployment.apps/spring-cloud-b 1/1 1 1 74s deployment.apps/spring-cloud-c 1/1 1 1 83s deployment.apps/spring-cloud-gateway 1/1 1 1 57s
步驟三:部署spring-cloud-c、spring-cloud-a應用的灰階版本
登入Container Service管理主控台。使用如下YAML部署spring-cloud-c應用的灰階版本:
使用如下YAML部署spring-cloud-a應用的灰階版本:
步驟四:建立灰階環境泳道組
登入MSE治理中心控制台,並在頂部功能表列選擇地區。
在左側導覽列,選擇。
在全鏈路灰階頁面頂部,選擇微服務命名空間。您選擇的微服務命名空間內如果沒有泳道組,請單擊建立泳道組及泳道;如果已存在泳道組,則請單擊+建立泳道組。
在建立泳道組面板,單擊+ 建立泳道組,在建立泳道組頁面,設定如下相關配置,然後單擊確定。
配置項
說明
泳道組名稱
自訂泳道組的名稱。
入口類型
選擇Java服務網關。
入口應用
選擇spring-cloud-gateway。
泳道組涉及應用
選擇spring-cloud-a、spring-cloud-b和spring-cloud-c。
泳道組建立完成後,在全鏈路灰階頁面的泳道組地區,可以查看您建立的泳道組。如需變更泳道組資訊,單擊
表徵圖,可在頁面自行修改相關資訊。
步驟五:建立灰階環境泳道
使用全鏈路灰階功能時,需要您給灰階應用添加一個特殊的
tag標記,以便將這些節點和其他節點區分開來。容器環境下需要您在spec.template.metadata.labels下增加alicloud.service.tag: ${tag}資訊。ECS 環境下需要添加Java啟動參數-Dalicloud.service.tag=${tag}。以Java網關作為全鏈路灰階入口時,MSE支援兩種泳道模式。
按請求內容灰階:當請求內容可以用於灰階識別時,建議採用此種灰階模式。如果不可以,也強烈建議您通過系統改造增加此類灰階標識,以便獲得更好的灰階效果。比如,可以保持灰階請求前後的一致性。
按比例路由灰階:當請求內容無法用於灰階識別且遺留系統也無法進行改造時,可以採用此種退化的灰階模式。該模式有一定弊端,可能導致同一來源的請求進入不同泳道,而造成灰階請求前後行為的不一致。
泳道路由模式在一個泳道組中需要保持一致。您只有在建立泳道組中第一條泳道時可以調整網關路由規則Path和泳道路由模式。
在全鏈路灰階頁面底部,單擊點擊建立第一個分流泳道。如果您選擇的微服務空間內已經建立過泳道,則單擊建立泳道。
在建立泳道面板,設定流控泳道相關配置,然後單擊確定。
配置項 | 說明 |
配置節點標籤 | 需要您手工給您的灰階應用節點打上標籤,用來和正常節點做區分。 |
填寫泳道資訊 | 泳道標籤:該泳道內的匹配的流量去往的目標標籤。 確認匹配關係:檢查您配置了該標籤的應用節點數是否符合預期。 |
配置路由和灰階規則 | 設定流量進入該泳道的規則。
說明 您還可以為每條網關path分別設定不同的流量比例,開啟該功能時,您需要注意該每條path當前在所有泳道組中配置的流量比例總和不應超過100%。 |
建立按請求內容路由的泳道
配置項 | 說明 |
配置節點標籤 | 需要您給灰階應用節點打上標籤,用來和正常節點做區分。 |
填寫泳道資訊 | 泳道標籤:該泳道內所匹配的流量去往的目標標籤。本樣本將泳道目標標籤設定為gray。 確認匹配關係:檢查您配置了該標籤的應用節點數是否符合預期。 |
配置路由和灰階規則 | 設定相應的路由規則條件。
|
建立按比例路由的泳道
請確保MSE Java Agent的版本為3.2.3及以上,否則會影響百分比灰階能力。
配置項 | 說明 |
配置節點標籤 | 需要您給灰階應用節點打上標籤,用來和正常節點做區分。 |
填寫泳道資訊 | 泳道標籤:該泳道內所匹配的流量去往的目標標籤。本樣本將泳道目標標籤設定為gray。 確認匹配關係:檢查您配置了該標籤的應用節點數是否符合預期。 |
配置路由和灰階規則 | 設定相應的路由規則條件。
|
完成泳道建立後,在全鏈路灰階的流量分配地區,可以查看泳道詳情,還可以進行如下操作。
在操作列,選擇開啟,建立的泳道將會生效,即流量會按照泳道方式進行流轉,滿足規則的流量會優先流向標記有當前泳道對應標籤的應用版本,如果沒有對應標籤的應用版本,則流向未打標的應用版本。
在操作列,選擇關閉,關閉建立的泳道,即該應用往後的流量會流向未打標的應用版本。
單擊
表徵圖,可以查看該泳道的流量比例。單擊
表徵圖,可以設定該泳道上應用的狀態。
步驟六:測試基準及灰階版本流量
測試按請求內容路由的泳道
使用curl命令測試基準流量:
curl 8.130.x.x/A/a A[192.168.x.x][config=base] -> B[192.168.x.x] -> C[192.168.x.x]說明命令中的
8.130.x.x是Spring Cloug Gateway暴露出的公網IP地址。使用curl命令測試灰階流量:
curl 8.130.x.x/A/a?name=xiaoming Agray[192.168.x.x][config=base] -> B[192.168.x.x] -> Cgray[192.168.x.x]說明當參數帶上
name=xiaoming時,會命中灰階標籤,並向後透傳。比如灰階請求到A應用和C應用時,會請求到Agray和Cgray節點。
請求到B應用時,由於不存在Bgray節點,仍然會請求B的基準節點。
測試按比例路由的泳道
通過如下Python3指令碼測試按比例路由的分流情況(需要安裝requests包)。注意將x.x.x.x替換為spring-cloud-gateway網關的入口SLB地址。
# pip3 install requests
# python3 traffic.py
import requests
TOTAL_REQUEST = 100
ENTRY_URL = 'http://x.x.x.x/A/a'
def parse_tag(text:str):
'''
A[10.0.23.64][config=base] -> B[10.0.23.65] -> C[10.0.23.61]
Agray[10.0.23.64][config=base] -> B[10.0.23.65] -> Cgray[10.0.23.61]
Ablue[10.0.23.64][config=base] -> B[10.0.23.65] -> Cblue[10.0.23.61]
'''
print(text)
app_parts = text.split(' -> ')
# tag_app: C[10.0.23.61] / Cgray[10.0.23.61]
tag_app = app_parts[-1]
splits = tag_app.split('[')
# tag_part: C / Cgray
tag_part = splits[0]
tag = tag_part[1:]
return tag if len(tag) > 0 else 'base'
def get_tag(url:str):
resp = requests.get(url)
resp.encoding = resp.apparent_encoding
return parse_tag(resp.text)
def cal_tag_count(url:str, total_request:int):
count_map = {}
for i in range(total_request):
tag = get_tag(url)
if tag not in count_map:
count_map[tag] = 1
else:
count_map[tag] += 1
print()
print('Total Request:', total_request)
print('Traffic Distribution:', count_map)
if __name__ == '__main__':
cal_tag_count(ENTRY_URL, TOTAL_REQUEST)從結果可以看到,約有30%的流量去往了灰階環境。

步驟七:可觀測
若應用出現異常,您可以通過MSE提供的可觀測能力查看異常資料,協助您快速定位問題。
微服務治理可觀測
在MSE微服務治理的全鏈路灰階頁面,單擊目標應用,在應用 QPS 監控地區,可查看對應泳道基準版本和灰階版本的流量情況。

總QPS:該應用總的QPS。
異常QPS:該應用出錯的請求數。
GrayQPS:該應用的灰階版本的QPS。