End-to-end canary release with a self-managed Spring Cloud Gateway or Zuul
Spring Cloud Gateway and Zuul are common API gateways in a microservice architecture that support route forwarding and filter processing. You can configure routing rules to route requests to a canary environment for validating and testing a canary version. The end-to-end canary release feature in Microservices Engine (MSE) lets you implement end-to-end traffic throttling without modifying your business code. This topic shows you how to configure a Spring Cloud Gateway or Zuul gateway to enable an end-to-end canary release.
Prerequisites
Background
This topic demonstrates how to use MSE for an end-to-end canary release by simulating a real-world service call chain. You can implement this feature without modifying your application code. Simply configure a traffic rule for the ingress application. MSE then propagates this tag throughout the service call chain. During each service call, MSE preferentially routes traffic that matches the canary condition to the corresponding canary version. If a corresponding canary version does not exist, the traffic automatically falls back to the base version (also known as the stable version).
In this example, four business applications (spring-cloud-gateway, spring-cloud-a, spring-cloud-b, and spring-cloud-c) and a Nacos Server that acts as the registry are deployed. The service call chain is: spring-cloud-gateway->A->B->C.
Calls between applications include both Spring Cloud and Dubbo service calls.
End-to-end canary release uses traffic tagging to preferentially route canary traffic to canary nodes. This allows you to perform controlled canary validation and ensure system stability.
End-to-end canary release validation typically uses the following strategies:
-
Directing a small percentage of live production traffic to the canary version for testing.
-
Filtering live production traffic based on specific rules, such as a specified header or cookie.
This topic describes how to configure both of these strategies to support various canary release scenarios within a microservices architecture.
Step 1: Connect applications to MSE
Connect microservice applications in a Container Service for Kubernetes (ACK) cluster to Microservice Engine (MSE). You can choose a connection method based on your requirements. For more information, see Connect microservice applications in an ACK cluster to Microservice Engine (MSE).
Connect by namespace
-
Log on to the Microservice Engine (MSE) console and select a region in the top navigation bar.
-
In the left-side navigation pane, choose Microservices Governance > Application Governance.
-
On the Application list page, click ACK Application Access.
-
In the ACK Application Access dialog box, configure the parameters and click OK.
Parameter
Description
Cluster type
Select ACK Cluster, ACK Serverless Cluster, or ACS Cluster.
NoteIf you have not authorized Container Service to access Microservice Engine (MSE), click Authorize.
Cluster Name/ID
Select the Cluster Name/ID of the target cluster. You can search by keyword.
ack-onepilot
Displays the connection status of ack-onepilot. For more information about the ack-onepilot component and how to upgrade it, see ack-onepilot component and Install and upgrade the Microservice Engine (MSE) component.
-
If ack-onepilot is not installed, the system automatically starts the installation after you select an ACK cluster. A message appears, indicating the installation takes about one minute.
If you use a RAM user and receive a permission error, log on to the Container Service for Kubernetes console, go to the target cluster, click Component Management, find ack-onepilot, and then click Install.
-
If ack-onepilot is already installed, the console displays its status as "Installed" followed by the version number, for example, Installed 4.2.0.
Note-
This step connects the ack-onepilot component. To view its details, log on to the Container Service for Kubernetes console, navigate to the target cluster, and then choose Operations & Maintenance > Component Management.
-
After ack-onepilot is installed, it automatically injects a probe, which may increase the application startup time by up to 10 seconds.
-
When you connect applications using the namespace-based method, if the target cluster is not in one of the following regions, ensure the cluster can access the public network and connect to acm.aliyun.com:8080: China (Qingdao), China (Hangzhou), China (Beijing), China (Shanghai), China (Shanghai-Finance), China (Shenzhen), China (Hong Kong), Singapore, Germany (Frankfurt), Australia (Sydney), US (Silicon Valley), and US (Virginia).
Access Type
Select Namespace Access.
Cluster Namespace
Select a Cluster Namespace.
Microservices Governance Namespace
Select a Microservices Governance Namespace.
-
Connect by single application
-
Log on to the Microservice Engine (MSE) console and select a region in the top navigation bar.
-
In the left-side navigation pane, choose Microservices Governance > Application Governance.
-
On the Application list page, click ACK Application Access.
-
In the ACK Application Access dialog box, configure the parameters and click OK.
Parameter
Description
Cluster type
Select ACK Cluster, ACK Serverless Cluster, or ACS Cluster.
NoteIf you have not authorized Container Service to access Microservice Engine (MSE), click Authorize.
Cluster Name/ID
Select the Cluster Name/ID of the target cluster. You can search by keyword.
ack-onepilot
Displays the connection status of ack-onepilot. For more information about the ack-onepilot component and how to upgrade it, see ack-onepilot component and Install and upgrade the Microservice Engine (MSE) component.
-
If ack-onepilot is not installed, the system automatically starts the installation after you select an ACK cluster. A message appears, indicating the installation takes about one minute.
If you use a RAM user and receive a permission error, log on to the Container Service for Kubernetes console, go to the target cluster, click Component Management, find ack-onepilot, and then click Install.
-
If ack-onepilot is already installed, the console displays its status as "Installed" followed by the version number, for example, Installed 4.2.0.
Note-
This step connects the ack-onepilot component. To view its details, log on to the Container Service for Kubernetes console, navigate to the target cluster, and then choose Operations & Maintenance > Component Management.
-
After ack-onepilot is installed, it automatically injects a probe, which may increase the application startup time by up to 10 seconds.
-
When you connect applications using the namespace-based method, if the target cluster is not in one of the following regions, ensure the cluster can access the public network and connect to acm.aliyun.com:8080: China (Qingdao), China (Hangzhou), China (Beijing), China (Shanghai), China (Shanghai-Finance), China (Shenzhen), China (Hong Kong), Singapore, Germany (Frankfurt), Australia (Sydney), US (Silicon Valley), and US (Virginia).
Access Type
Select Single Application Access.
Access Procedure
Follow the steps provided.
Step 1: Go to the Workloads > Deployments page of the cluster and switch to the application's namespace.
Step 2: Find the target application and click View YAML.
Step 3: Edit the labels in the following format and click Update.
spec: template: metadata: labels: # Set to "on" to enable the connection. The value must be enclosed in double quotation marks. msePilotAutoEnable: "on" # Specify the governance namespace. If the namespace does not exist, it is automatically created. mseNamespace: default # Specify the application name to connect to MSE. The name must be enclosed in double quotation marks. msePilotCreateAppName: "your-deployment-name" -
Step 2: Deploy applications
-
Log on to the Container Service for Kubernetes (ACK) console. In the left-side navigation pane, choose Clusters.
-
On the Clusters page, click your target cluster. In the left-side navigation pane, choose .
-
On the Deployments page, select a Namespaces and then click Create from YAML.
This example deploys a Nacos Server as a registry, along with four business applications: spring-cloud-gateway, spring-cloud-a, spring-cloud-b, and spring-cloud-c. You can also get the source code from the Demo.
-
YAML for the Nacos Server (registry)
-
YAML for the spring-cloud-c application
-
YAML for the spring-cloud-b application
-
YAML for the spring-cloud-a application
-
YAML for the spring-cloud-gateway application
Run the following command to check the deployment status:
kubectl get svc,deployExpected output:
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 -
Step 3: Deploy canary versions of spring-cloud-c and spring-cloud-a
-
Log in to the ACK console. Use the following YAML to deploy the canary version of the spring-cloud-c application:
-
Use the following YAML to deploy the canary version of the spring-cloud-a application:
Step 4: Create a canary lane group
-
Log on to the MSE Governance Center console and select a region in the top navigation bar.
-
In the left-side navigation pane, choose .
-
On the End-to-end Canary Release page, select a microservice namespace at the top of the page. If no lane group exists in the selected microservice namespace, click Create Lane Group and Lane. If a lane group already exists, click + Create Lane Group.
-
In the Create Lane Group panel, click + Create Lane Group. On the Create Lane Group page, configure the following parameters and then click OK.
Parameter
Description
Lane group name
Enter a custom name for the lane group.
Ingress type
Select java service gateway.
ingress application
Select spring-cloud-gateway.
lane group application
Select spring-cloud-a, spring-cloud-b, and spring-cloud-c.
After the lane group is created, you can view it in the lane group section of the End-to-end Canary Release page. To edit the lane group, click the
icon.
Step 5: Create a canary lane
-
To use the end-to-end canary release feature, add a special
tagto your canary applications to distinguish them from other nodes. In a container environment, addalicloud.service.tag: ${tag}underspec.template.metadata.labels. In an ECS environment, add the Java startup parameter-Dalicloud.service.tag=${tag}. -
If you use a Java microservice gateway as the ingress for an end-to-end canary release, MSE supports two lane routing modes.
-
Canary release by content: This mode is recommended if you can identify canary traffic from the request content. If not, modify your system to include a unique identifier in requests. This ensures that all requests within a session are routed consistently.
-
Canary release by ratio: Use this mode as a fallback if you cannot identify canary traffic from request content and cannot modify the legacy system. The drawback is that requests from the same source might be routed to different lanes, resulting in inconsistent behavior.
-
-
The lane routing mode must be consistent across all lanes in a lane group. You can only adjust the gateway routing rule Path and the lane routing mode when creating the first lane in the group.
-
At the bottom of the End-to-end Canary Release page, click Click to Create First Split Lane. If a lane already exists in the selected microservice space, click Create Lane.
-
In the Create Lane panel, configure the lane parameters and click OK.
|
Parameter |
Description |
|
Add node tag |
Manually add a tag to your canary application nodes to distinguish them from regular nodes. |
|
Enter lane information |
Lane Tag: The destination tag for traffic that matches the lane rules. Confirm Matching Relationship: Verify that the number of application nodes with this tag is correct. |
|
Configure routing and canary release rules |
Define the rules for routing traffic into this lane.
Note
You can also set different traffic percentages for each gateway path. If you use this feature, ensure that the total traffic percentage for the same path across all lane groups does not exceed 100%. |
Route by content
|
Parameter |
Description |
|
Add node tag |
Manually add a tag to your canary application nodes to distinguish them from regular nodes. |
|
Enter lane information |
Lane Tag: The destination tag for traffic that matches the conditions of this lane. This example sets the lane tag to gray. Confirm Matching Relationship: Verify that the number of application nodes with this tag is correct. |
|
Configure routing and canary release rules |
Set the routing rule conditions.
|
Route by ratio
Ensure the MSE Java agent is version 3.2.3 or later. Otherwise, percentage-based canary releases may not function correctly.
|
Parameter |
Description |
|
Add node tag |
Manually add a tag to your canary application nodes to distinguish them from regular nodes. |
|
Enter lane information |
Lane Tag: The destination tag for traffic that matches the conditions of this lane. This example sets the lane tag to gray. Confirm Matching Relationship: Verify that the number of application nodes with this tag is correct. |
|
Configure routing and canary release rules |
Set the routing rule conditions.
|
After creating the lane, you can view its details in the Traffic Distribution section of the End-to-end Canary Release page and perform the following actions:
-
In the Actions column, click Enable. This activates the lane and routes traffic according to its rules. Traffic that matches the rule is preferentially routed to the application version with the corresponding lane tag. If no such version exists, the traffic is routed to the untagged application version.
-
In the Actions column, click Close. This deactivates the lane, and subsequent traffic is routed to the untagged application version.
-
Click the
icon to view the traffic percentage for the lane. -
Click the
icon to set the status of the applications in the lane.
Step 6: Test base and canary traffic
By request content
-
Run the following
curlcommand to test base traffic:curl 8.130.x.x/A/a A[192.168.x.x][config=base] -> B[192.168.x.x] -> C[192.168.x.x]NoteIn the command,
8.130.x.xis the public IP address exposed by the Spring Cloud Gateway. -
Run the following
curlcommand to test canary traffic: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]Note-
When the request includes the parameter
name=xiaoming, it matches the canary tag, which is then propagated downstream. -
For example, a request with a canary tag sent to applications A and C is routed to the canary nodes for applications A and C.
-
When the request reaches application B, it is routed to the base node because a canary node for application B does not exist.
-
By ratio
To test traffic splitting by ratio, use the following Python 3 script. Make sure the requests package is installed and replace x.x.x.x with the ingress SLB address for your Spring Cloud Gateway.
# 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)
After running the script, the output shows approximately 30% of the traffic is routed to the canary environment.
Step 7: Observability
If an application issue occurs, use MSE's observability to view exception data and quickly locate the problem.
Microservices Governance observability
On the End-to-end Canary Release page of MSE Microservices Governance, click the target application. The Application QPS Monitoring section shows traffic data for the base and canary versions of the corresponding lane.

-
Total QPS: Total queries per second (QPS) for the application.
Exception QPS: The number of failed requests for the application.
-
CanaryQPS: Queries per second (QPS) for the application's canary version.