You can control traffic in asynchronous scenarios, such as message queues, to implement an end-to-end canary release without modifying business code. This topic shows you how to use MSE Microservices Governance to implement an end-to-end canary release for RocketMQ applications.
Prerequisites
Demo architecture
This topic provides an example of deploying applications in the ACK console. You can also use kubectl to deploy applications and simulate a real-world call chain. The following figure shows the architecture of the demo application. The calls between applications use both Spring Cloud and Dubbo, the two most common microservice frameworks. In this architecture, Application C produces RocketMQ messages that are consumed by Application A. When Application A consumes a message, it initiates a new call. These applications are based on standard implementations of Spring Cloud, Dubbo, and RocketMQ.

Step 1: Onboard applications to MSE Microservices Governance
-
Enable Microservices Governance for microservice applications in the Container Service for Kubernetes (ACK) cluster. You can select an appropriate method based on your business requirements. For more information, see Enable Microservices Governance for Java microservice applications in an ACK or ACS cluster.
Enable Microservices Governance for applications in an ACK namespace
-
Log on to the 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.
Set Onboarding Type to Namespace or Single Application. From the Container Cluster Namespace drop-down list, select the target namespace, such as
default. In the Governance Namespace field, enter a name for the corresponding namespace.Parameter
Description
Cluster type
Select ACK Cluster, ACK Serverless Cluster, or ACS Cluster.
NoteIf you have not authorized Container Service for Kubernetes to call MSE, click Authorize Now to grant the required permissions.
Cluster Name/ID
Select the Cluster Name/ID of the cluster that you want to connect to the MSE governance center. You can search for the cluster by keyword.
ack-onepilot
Displays the status of the ack-onepilot component. For more information about this component and how to upgrade it, see ack-onepilot component and Install and upgrade the MSE microservices governance component.
-
If ack-onepilot is not installed, the system automatically starts the installation after you select a cluster and displays the message "The installation process takes about 1 minute. Wait for a while."
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, and in the navigation pane on the left, click Add-ons. Find ack-onepilot and click Install.
-
If ack-onepilot is already installed, the UI displays the installed version, for example,
Installed 4.2.0.
Note-
You can view details about the ack-onepilot component by logging on to the Container Service for Kubernetes console, navigating to the target cluster, and choosing Operations > Add-ons.
-
After ack-onepilot is installed, it automatically injects a Java agent. This may increase application startup time by up to 10 seconds.
-
When connecting by namespace, if your target cluster is not in one of the listed regions, ensure it has public network access and can connect to acm.aliyun.com:8080: China (Qingdao), China (Hangzhou), China (Beijing), China (Shanghai), Shanghai Finance Cloud, China (Shenzhen), Hong Kong (China), Singapore, Germany (Frankfurt), Australia (Sydney), US (Silicon Valley), and US (Virginia).
Access Type
Select Namespace Access.
Cluster Namespace
Select the Cluster Namespace.
Microservices Governance Namespace
Select a Microservices Governance Namespace.
-
Enable Microservices Governance for an application
-
Log on to the 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.
Set Onboarding Type to Single Application. In the Edit Labels (YAML format) section, add the following labels under
spec.template.metadata.labelsin the application's Deployment YAML file:msePilotAutoEnable: "on"to enable microservices governance,mseNamespace: defaultto specify the MSE namespace, andmsePilotCreateAppName: "your-deployment-name"to set the application name. Replaceyour-deployment-namewith the actual Deployment name.Parameter
Description
Cluster type
Select ACK Cluster, ACK Serverless Cluster, or ACS Cluster.
NoteIf you have not authorized Container Service for Kubernetes to call MSE, click Authorize Now to grant the required permissions.
Cluster Name/ID
Select the Cluster Name/ID of the cluster that you want to connect to the MSE governance center. You can search for the cluster by keyword.
ack-onepilot
Displays the status of the ack-onepilot component. For more information about this component and how to upgrade it, see ack-onepilot component and Install and upgrade the MSE microservices governance component.
-
If ack-onepilot is not installed, the system automatically starts the installation after you select a cluster and displays the message "The installation process takes about 1 minute. Wait for a while."
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, and in the navigation pane on the left, click Add-ons. Find ack-onepilot and click Install.
-
If ack-onepilot is already installed, the UI displays the installed version, for example,
Installed 4.2.0.
Note-
You can view details about the ack-onepilot component by logging on to the Container Service for Kubernetes console, navigating to the target cluster, and choosing Operations > Add-ons.
-
After ack-onepilot is installed, it automatically injects a Java agent. This may increase application startup time by up to 10 seconds.
-
When connecting by namespace, if your target cluster is not in one of the listed regions, ensure it has public network access and can connect to acm.aliyun.com:8080: China (Qingdao), China (Hangzhou), China (Beijing), China (Shanghai), Shanghai Finance Cloud, China (Shenzhen), Hong Kong (China), Singapore, Germany (Frankfurt), Australia (Sydney), US (Silicon Valley), and US (Virginia).
Access Type
Select Single Application Access.
Access Procedure
Follow these steps.
Step 1: In the Container Service for Kubernetes console, navigate to the Workloads > Deployments page of your cluster and switch to your application's namespace.
Step 2: Find the target application and click Edit YAML.
Step 3: Edit the
labelsfield as shown in the following example and click Update.spec: template: metadata: labels: # Set to "on" to enable connection. The value must be enclosed in double quotation marks. msePilotAutoEnable: "on" # Specify the target governance namespace. If the namespace does not exist, it is automatically created. mseNamespace: default # Specify the application name to be displayed in MSE. The value must be enclosed in double quotation marks. msePilotCreateAppName: "your-deployment-name" -
-
Step 2: Deploy the applications
Deploy the four business applications (spring-cloud-zuul, spring-cloud-a, spring-cloud-b, and spring-cloud-c), a Nacos Server for service registration, and a RocketMQ Server for messaging. You can find the source code for these components in this demo.
The spring-cloud-zuul application forwards requests from its /A/dubbo path to spring-cloud-a. Then, spring-cloud-a uses the Dubbo protocol to call spring-cloud-b, which in turn calls spring-cloud-c using the same protocol. After receiving the request, spring-cloud-c produces a message and returns its environment tag and IP address. These messages are consumed by the spring-cloud-a application. When consuming a message, spring-cloud-a calls spring-cloud-b by using Spring Cloud, which then calls spring-cloud-c. The final result is written to the logs of spring-cloud-a.
# When a request is sent to /A/dubbo, the returned value is: A[10.25.xx.xx] -> B[10.25.xx.xx] -> C[10.25.xx.xx]
# At the same time, after Application A receives the message, the following log is generated:
2021-12-28 10:58:50.301 INFO 1 --- [essageThread_15] c.a.mse.demo.service.MqConsumer
: topic:TEST_MQ,producer:C[10.25.xx.xx],invoke result:A[10.25.xx.xx] -> B[10.25.xx.xx] -> C[10.25.xx.xx]
-
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Cluster List page, click the name of the destination cluster or click Details in the Actions column.
In the left navigation pane of the cluster management page, choose .
-
On the Stateless page, select a Namespaces and click Create from YAML. Use the following YAML file to deploy the applications:
-
Run the following command to check if the applications are deployed successfully:
kubectl get svc,deployExpected output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 192.168.xx.xx <none> 4xx/TCP 7d service/mqnamesrv ClusterIP 192.168.xx.xx <none> 98xx/TCP 47h service/nacos-server ClusterIP 192.168.xx.xx <none> 88xx/TCP 47h service/zuul-slb LoadBalancer 192.168.xx.xx 123.56.xx.xx 80:302xxx/TCP 47h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nacos-server 1/1 1 1 4m deployment.apps/rockectmq-broker 1/1 1 1 4m deployment.apps/rocketmq-name-server 1/1 1 1 5m deployment.apps/spring-cloud-a 1/1 1 1 5m deployment.apps/spring-cloud-b 1/1 1 1 5m deployment.apps/spring-cloud-c 1/1 1 1 5m deployment.apps/spring-cloud-zuul 1/1 1 1 5m
Step 3: Enable message canary release
Assume that spring-cloud-c produces messages and spring-cloud-a consumes them. Enable canary release for messaging for both applications.
-
To enable or disable the canary release for messaging feature, you must redeploy the application in the ACK console for the change to take effect.
-
The feature takes effect only when it is enabled for both the message producer and the message consumer.
-
This feature supports only RocketMQ, including open-source Apache RocketMQ and Alibaba Cloud Message Queue for Apache RocketMQ.
-
If you use open-source Apache RocketMQ, both the RocketMQ Server and RocketMQ Client must be version 4.5.0 or later.
-
If you use Alibaba Cloud Message Queue for Apache RocketMQ 4.x, you must use the Platinum Edition to filter messages based on SQL-92 expressions. This limitation does not apply if you use client-side filtering or Message Queue for Apache RocketMQ 5.x.
-
If you use the Ons Client, you must use version 1.8.0.Final or later.
-
-
After you enable canary release for messaging, MSE modifies the consumer group name. For example, if the original consumer group is
group1and the environment tag isgray, the new consumer group becomesgroup1_gray. If you use Alibaba Cloud Message Queue for Apache RocketMQ, you must create this new group in advance. -
By default, MSE uses the SQL-92 standard to filter messages. If you use open-source Apache RocketMQ, you must enable SQL-92 filtering on the server by adding
enablePropertyFilter=trueto thebroker.conffile. -
If your scenario does not support SQL-92 filtering, you can use the
FilterMessageHookclass for client-side filtering. This method requires you to enable canary release for messaging and select the client-side filtering option for all applications. However, this approach is not recommended for production environments because it processes all messages in every environment, which places a heavy load on both producers and consumers.
-
Log on to the 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 the resource card of the desired application. In the left-side navigation pane, click Traffic management.
-
On the Canary Release for Messaging tab, turn on the switch and click OK.
Configure Tags Ignored by Untagged Environment to
gray, and set Message Canary Release Filter to Server-side Filtering (Recommended). -
In the ACK console, redeploy the application in the ACK console for the configuration to take effect.
Step 4: Deploy the new application versions
Deploy the canary versions of the applications: spring-cloud-a-gray, spring-cloud-b-gray, and spring-cloud-c-gray.
-
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Cluster List page, click the name of the destination cluster or click Details in the Actions column.
In the left navigation pane of the cluster management page, choose .
-
On the Stateless page, select a Namespaces and click Create from YAML. Use the following YAML file to deploy the applications:
Step 5: Route traffic and verify
-
Log on to the MSE console, and select a region in the top navigation bar.
-
In the left-side navigation pane, choose Microservices Governance > Application Governance.
-
Click the resource card for the
spring-cloud-aapplication. On the Application Overview page, observe the QPS Trend Chart chart to confirm that all traffic is routed to the base environment of thespring-cloud-aapplication, which is the stable version. -
In the left navigation bar, click Traffic management, and then click the Tag-based Routing tab. In the Traffic Rule column for the
graytag, click Add. -
In the Create Tag-Based Routing panel, configure the traffic rule, and then click OK.
In this example, the traffic rule is set to
name=xiaoming. For more information about how to configure traffic rules, see Configure tag-based routing.On the Create Tag Route page, configure the following settings:
Route Name: test-a
Application: spring-cloud-a
Tag: gray
Link Delivery: Enabled
Framework Type: Spring Cloud
Path: /dubbo
Condition Mode: All conditions must be met
After the traffic rule takes effect, you can view the traffic distribution on the Application Overview page.
-
On the Tag-based Routing tab, click the name of the rule associated with the gray tag. In the Rule details panel that appears, click Edit. In the Edit Tag-Based Routing panel, enable Trace Propagation and click OK.
NoteAfter you enable context propagation, canary traffic that matches the
name=xiaomingrule propagates throughout the entire call chain. You do not need to configure the rule for each application. -
Log on to the ACK console. In the left navigation pane, click Clusters.
-
On the Clusters page, click the name of your cluster. In the left navigation pane, click .
-
Click the zuul-slb service. In the Basic Information section, click the address next to External IP.
-
On the service call page, enter /A/dubbo?name=xiaoming and click Start Call.
The end-to-end canary release is now active.
On the test page, enter the URL
/A/dubbo?name=xiaomingand click Start Invocation. The invocation log shows all requests routed through canary nodes: Agray[10.5.117.199] → Bgray[10.5.117.200] → Cgray[10.5.117.157].The following figure shows the request data for the spring-cloud-b application.

Step 6: Adjust message tag filtering and verify
-
Log on to the MSE Microservices Governance console.
-
In the navigation pane on the left, choose , and then click the resource card for the spring-cloud-a application.
-
In the left-side navigation pane, click Traffic management, and then click the Canary Release for Messaging tab.
-
On the Canary Release for Messaging tab, click Edit next to Tags Ignored in Base Environment. In the input box, select
grayand click OK.Selecting
grayfor the Tags to ignore in the base environment parameter means that messages with thegrayenvironment tag can be consumed only byspring-cloud-a-grayand not byspring-cloud-a. The configuration for the Tags to ignore in the base environment parameter takes effect dynamically, and you do not need to perform a restart.NoteBy default, a base environment node consumes messages from all environments. To prevent it from consuming messages produced by a specific tagged environment, simply configure the Tags to be ignored by the base environment parameter.
-
Log on to the ACK console and view the logs for the spring-cloud-a application to verify the configuration.
The logs show that before this change, the base environment consumed messages from both the
grayand base environments. After setting the Tags Ignored by Base Environment parameter togray, the base environment consumes only messages produced in the base environment.In the MqConsumer log of the spring-cloud-a container, canary messages are routed through Bgray→Cgray, while baseline messages are routed through A→B→C, following separate paths.
2021-12-28 11:51:47.880 INFO 1 --- [essageThread_11] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:Cgray[10.xxx 2],invoke result:A[10.xxx,xxx100] -> Bgray[xxx] -> Cgray[xxx] 2021-12-28 11:51:47.942 INFO 1 --- [essageThread_10] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.xxx],invoke result:A[10.xxx 00] -> B[1 0.25.xxx] -> C[xxx 7] 2021-12-28 11:51:48.783 INFO 1 --- [MessageThread_8] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.2xxx 7],invoke result:A[10.xxx] -> B[1 0.25xxx] -> C[10.xxx 7] 2021-12-28 11:51:48.885 INFO 1 --- [essageThread_12] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:Cgray[10.2xxx 2],invoke result:A[10.2xxx] -> Bgray[10.25 xxx] -> Cgray[10.25xxx102] 2021-12-28 11:51:50.908 INFO 1 --- [essageThread_17] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.xxx.157],invoke result:A[10.2xxx 00] -> B[1 0.25.xxx] -> C[10.2xxx57] 2021-12-28 11:51:50.909 INFO 1 --- [essageThread_16] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:Cgray[10.25.xxx 2],invoke result:A[10.2xxx100] -> Bgray[10.xxx25] -> Cgray[10.xxx.02] 2021-12-28 11:51:51.642 INFO 1 --- [essageThread_14] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:Cgray[10.25xxx],invoke result:A[10.25.xxx] -> Bgray[10.xxx.25] -> Cgray[10.xxx 102] 2021-12-28 11:51:51.684 INFO 1 --- [essageThread_15] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.25xxx57],invoke result:A[10.xxx0] -> B[1 0.25.xxx] -> C[10.xxx 7] 2021-12-28 11:51:52.765 INFO 1 --- [essageThread_13] c.a.mse.demo.service.MqConsumer : topic:TEST_MQ,producer:C[10.25.xxx],invoke result:A[10.25.xxx] -> B[1