Routing all users to a new frontend version at once risks exposing everyone to defects. Frontend canary release routes a subset of users -- identified by a cookie or header value -- to the new version first. You can monitor for issues with the small group, then gradually expand or roll back without affecting other users.
Microservices Engine (MSE) cloud-native gateways support frontend canary release through the frontend-gray plug-in. The plug-in inspects each request for a user identifier, matches it against your canary rules, and routes the request to either the base or canary version.
How it works
Each user request passes through the MSE cloud-native gateway. After authentication, the request cookie contains a unique user identifier, such as userid: 001. The frontend-gray plug-in evaluates this identifier against configured rules and forwards the request to the matching frontend version.
User request --> Cloud-native gateway --> frontend-gray plug-in evaluates userid
|-- Matches canary rule --> Canary version
|-- No match --> Base versionThe plug-in supports two routing strategies:
| Strategy | How it works | Use case |
|---|---|---|
| Rule-based | Routes users whose identifier matches a whitelist (grayKeyValue) to the canary version | Target specific test users or internal teams |
| Weight-based | Routes a percentage of non-rule-matched traffic to the canary version (weight) | Gradually roll out to a broader audience |
When both strategies are configured, rule-based matching is evaluated first. If a request does not match any rule, weight-based routing applies.
To extend canary release beyond the frontend to your entire microservices call chain, combine this approach with end-to-end canary release based on cloud-native gateways. This is useful when your frontend calls Spring Cloud or Dubbo backend services that also have canary versions.
Prerequisites
Before you begin, make sure that you have:
A Container Service for Kubernetes (ACK) managed cluster. For more information, see Create an ACK managed cluster
An MSE cloud-native gateway. For more information, see Create an MSE cloud-native gateway
Choose a deployment approach
MSE supports four approaches for frontend canary release. Choose the one that matches your infrastructure:
| Approach | When to use | Key difference |
|---|---|---|
| MSE Ingress gateway | Kubernetes workloads with Ingress-based routing | Traffic splitting defined through Ingress annotations |
| ACK cluster with MSE console routes | Kubernetes workloads with console-managed routing | Routes configured in the MSE console instead of Ingress resources |
| ECS instances | Applications deployed directly on ECS | Services registered by fixed IP address |
| CDN or OSS | Static frontend assets hosted in OSS | Plug-in rewrites paths to serve versioned assets from OSS |
MSE Ingress gateway
Step 1: Deploy the base and canary applications
Deploy two versions of your frontend application in the ACK cluster: a base Deployment and a canary Deployment, each with its own Service and Ingress resource. For details, see Create a stateless application using a Deployment.
Install MSE Ingress Controller before proceeding. For setup instructions, see Use MSE Ingress gateways to access services in ACK clusters and ACS clusters.
The canary Ingress uses three annotations to enable header-based traffic splitting:
| Annotation | Purpose |
|---|---|
nginx.ingress.kubernetes.io/canary: 'true' | Marks this Ingress as a canary route |
nginx.ingress.kubernetes.io/canary-by-header: x-higress-tag | Specifies the header used for routing decisions |
nginx.ingress.kubernetes.io/canary-by-header-value: gray | Routes requests with x-higress-tag: gray to the canary Service |
Step 2: Configure the frontend-gray plug-in
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. On the Gateways page, click the ID of the gateway.
In the left-side navigation pane, click Plug-in Marketplace.
On the Plug-in Marketplace page, search for
frontend-grayand click thefrontend-grayplug-in card.Click the Plug-in Configuration tab, choose Domain-level plug-in rules, and then click Add Rule. Configure the following rule: This rule routes users with
useridvalues00000002and00000003to the canary (gray) version. All other users see thebaseversion. For all available configuration fields, see Plug-in configuration reference and the Higress frontend-gray plug-in documentation.grayKey: userid rules: - name: beta-user grayKeyValue: - "00000002" - "00000003" baseDeployment: version: base grayDeployments: - name: beta-user version: gray enabled: true
Step 3: Verify the result
Log on to the ACK console. In the left-side navigation pane, click Clusters. Click the cluster that you created. In the left-side navigation pane, choose Network > Ingresses to find the public endpoint.

Open the public endpoint (for example,
nlb-qv04p*******cn-hangzhou.nlb.aliyuncsslb.com). Log on with theadmin/iceaccount. Confirm that the user ID is00000001and you see the base version.Log on with the
user/iceaccount. Confirm that the user ID is00000002and you see the canary version.
ACK cluster with MSE console routes
This approach uses the same Kubernetes workloads but configures routing through the MSE console instead of Ingress resources.
Step 1: Deploy the base and canary applications
Deploy the base and canary Deployments and Services in the ACK cluster. Use the same Deployment and Service manifests as the MSE Ingress gateway approach, but omit the Ingress resources. For details, see Create a stateless application using a Deployment.
Step 2: Configure the frontend-gray plug-in
Follow the same plug-in configuration steps as the MSE Ingress gateway approach.
Step 3: Add a service source
Register your ACK cluster as a service source so the gateway can discover your Kubernetes Services.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click the Source tab.
Click Add Source. In the Add Source panel, select Container Service for Source Type, select your ACK cluster from the ACK/ASK/ACS Cluster drop-down list, and then click OK.

Step 4: Add services
Import the base and canary Kubernetes Services into the gateway.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click the Services tab.
Click Add Service. In the Add Service panel, configure the parameters, and click OK.

Step 5: Add a base route
Create a route that directs default traffic to the base frontend Service.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click Add Route.
On the Add Route page, configure the parameters, and click Save and Advertise.

Step 6: Add a canary route
Create a route that directs canary traffic to the canary frontend Service.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click Add Route.
On the Add Route page, configure the parameters, and click Save and Advertise.
NoteSet the version to
gray. This value corresponds tograyDeployments.versionin thefrontend-grayplug-in configuration.
Step 7: Verify the result
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
On the Overview page, click the Endpoint tab to find the public endpoint.

Open the public endpoint (for example,
nlb-qv04p*******cn-hangzhou.nlb.aliyuncsslb.com). Log on with theadmin/iceaccount. Confirm that the user ID is00000001and you see the base version.Log on with the
user/iceaccount. Confirm that the user ID is00000002and you see the canary version.
ECS instances
Use this approach when frontend applications run directly on Elastic Compute Service (ECS) instances instead of Kubernetes.
Step 1: Deploy two frontend application versions on an ECS instance
Deploy the base and canary versions on the same or separate ECS instances:
Base version endpoint:
120.***.137.243:80Canary version endpoint:
120.***.137.243:8081
Step 2: Add services
Register both frontend versions as fixed-address services in the gateway.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click the Services tab.
Click Add Service. In the Add Service panel, select Fixed Address from the Service Source drop-down list, configure the parameters, and then click OK.


Step 3: Add a base route
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click Add Route.
On the Add Route page, configure the parameters, and click Save and Advertise.

Step 4: Add a canary route
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click Add Route.
On the Add Route page, configure the parameters, and click Save and Advertise.
NoteSet the version to
gray. This value corresponds tograyDeployments.versionin thefrontend-grayplug-in configuration.
Step 5: Configure the frontend-gray plug-in
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Plug-in Marketplace.
On the Plug-in Marketplace page, search for
frontend-grayand click thefrontend-grayplug-in card.Click the Plug-in Configuration tab, choose Domain-level plug-in rules, and then click Add Rule. Configure the following rule: For all available configuration fields, see Plug-in configuration reference and the Higress frontend-gray plug-in documentation.
grayKey: userid rules: - name: beta-user grayKeyValue: - "00000002" - "00000003" baseDeployment: version: base grayDeployments: - name: beta-user version: gray enabled: true
Step 6: Verify the result
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
On the Overview page, click the Endpoint tab to find the public endpoint.

Open the public endpoint (for example,
nlb-qv04p*******cn-hangzhou.nlb.aliyuncsslb.com). Log on with theadmin/iceaccount. Confirm that the user ID is00000001and you see the base version.Log on with the
user/iceaccount. Confirm that the user ID is00000002and you see the canary version.
CDN or OSS
Use this approach when frontend assets are hosted in Object Storage Service (OSS) and optionally served through CDN. The frontend-gray plug-in rewrites request paths to serve versioned assets from different OSS directories.
Step 1: Prepare your OSS file structure
Organize your frontend assets in OSS with version-based directories:
Step 2: Add a service
Register your OSS endpoint as a DNS-based service in the gateway.
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click the Services tab.
Click Add Service. In the Add Service panel, select DNS Domain Name from the Service Source drop-down list, enter the OSS endpoint, and then click OK.
ImportantIf OSS and the gateway are in the same region, use the internal OSS endpoint to avoid public network charges. If they are in different regions, use the public endpoint.

Step 3: Add a route
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Routes. Click Add Route.
On the Add Route page, configure the parameters, and click Save and Advertise.

Step 4: Configure the frontend-gray plug-in
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
In the left-side navigation pane, click Plug-in Marketplace.
On the Plug-in Marketplace page, search for
frontend-grayand click thefrontend-grayplug-in card.Click the Plug-in Configuration tab, choose Domain-level plug-in rules, and then click Add Rule. Configure the following rule: The CDN/OSS approach differs from the other approaches in the following fields: For all available configuration fields, see Plug-in configuration reference and the Higress frontend-gray plug-in documentation.
Field Description rewrite.hostThe OSS endpoint that hosts your frontend assets rewrite.indexRoutingMaps URL paths to versioned index.htmlfiles in OSS. The{version}placeholder is replaced by the version string (devor0.0.1)rewrite.fileRoutingMaps URL paths to versioned static asset directories in OSS baseDeployment.versionSet to dev(the base version directory name in OSS)grayDeployments[0].versionSet to 0.0.1(the canary version directory name in OSS)grayKey: userid rules: - name: beta-user grayKeyValue: - "00000002" - "00000003" rewrite: host: xx.oss-cn-shanghai.aliyuncs.com ## Replace with your OSS endpoint indexRouting: "/app1": "/project-a/app1/{version}/index.html" # Path rewrite for HTML entry pages fileRouting: "/app1": "/project-a/app1/{version}" # Path rewrite for CSS, JavaScript, and images baseDeployment: version: dev grayDeployments: - name: beta-user version: 0.0.1 enabled: true
Step 5: Verify the result
Log on to the MSE console. In the top navigation bar, select a region.
In the left-side navigation pane, choose Cloud-native Gateway > Gateways. Click the ID of the gateway.
On the Overview page, click the Endpoint tab to find the public endpoint.

Open the public endpoint (for example,
nlb-qv04p*******cn-hangzhou.nlb.aliyuncsslb.com). Log on with theadmin/iceaccount. Confirm that the user ID is00000001and you see the base version.Log on with the
user/iceaccount. Confirm that the user ID is00000002and you see the canary version.
Plug-in configuration reference
The following table lists the main configuration fields for the frontend-gray plug-in. For the complete field reference, see the Higress frontend-gray plug-in documentation.
| Field | Type | Required | Description |
|---|---|---|---|
grayKey | string | No | The key name used to extract the user identifier from a cookie or header. Example: userid |
graySubKey | string | No | A JSON sub-key within the grayKey value. Use this when the user identifier is embedded in a JSON-formatted cookie or header |
rules | array | Yes | A list of canary rules. Each rule defines a name and a set of user identifier values to match |
rules[].name | string | Yes | The name of the rule. Must match a corresponding entry in grayDeployments |
rules[].grayKeyValue | array of strings | No | A list of user identifier values. Requests with a matching identifier are routed to the corresponding canary version |
rules[].grayTagKey | string | No | An alternative key for matching. Use this for tag-based routing instead of user ID-based routing |
rules[].grayTagValue | array of strings | No | A list of tag values to match when using grayTagKey |
baseDeployment.version | string | Yes | The version identifier for the base (production) deployment |
grayDeployments | array | Yes | A list of canary deployments |
grayDeployments[].name | string | Yes | The canary deployment name. Must match a rule name in rules |
grayDeployments[].version | string | Yes | The version identifier for this canary deployment |
grayDeployments[].enabled | boolean | Yes | Whether this canary deployment is active |
grayDeployments[].weight | integer (0--100) | No | The percentage of non-rule-matched traffic to route to this canary version. Defaults to 0 |
rewrite | object | No | Path rewrite configuration for CDN/OSS deployments |
rewrite.host | string | No | The OSS endpoint hostname |
rewrite.indexRouting | map | No | Maps URL paths to versioned index.html files. Use {version} as a placeholder |
rewrite.fileRouting | map | No | Maps URL paths to versioned static asset directories. Use {version} as a placeholder |
injection | object | No | HTML injection configuration. Injects scripts or styles into the HTML entry page |
injection.head | array of strings | No | HTML snippets to inject into the <head> tag |
injection.body.first | array of strings | No | HTML snippets to inject at the beginning of the <body> tag |
injection.body.last | array of strings | No | HTML snippets to inject at the end of the <body> tag |
Monitor and roll back
After you deploy a canary release, monitor the canary version for issues before promoting it to all users.
Monitor the canary version:
Check the MSE gateway logs for error rates on canary routes. Compare error rates between the base and canary versions.
Use Cloud Monitor or Application Real-Time Monitoring Service (ARMS) to track page load times, JavaScript errors, and API success rates for canary users.
Set up alerts for abnormal metrics such as elevated HTTP 5xx error rates or increased page load latency on canary routes.
Roll back the canary version:
If the canary version shows problems, roll back by disabling the canary deployment:
Log on to the MSE console. Navigate to your gateway's Plug-in Marketplace and open the
frontend-grayplug-in configuration.Set
enabled: falsein thegrayDeploymentssection, or remove the canary rule entirely:grayDeployments: - name: beta-user version: gray enabled: false # Disables canary routing; all traffic goes to the base versionSave the configuration. All traffic immediately returns to the base version.
Promote the canary version:
After successful validation, promote the canary version by updating the base deployment image to the canary version image and removing the canary rules from the plug-in configuration.
FAQ
Can I use rewrite policies and frontend canary release at the same time?
It depends on your service source:
Non-CDN/OSS sources (ACK, ECS): Yes. Rewrite policies and canary release work independently and do not conflict.
CDN or OSS sources: No. The
frontend-grayplug-in handles path rewriting internally through therewriteconfiguration block. Adding a separate rewrite policy causes conflicts and may return HTTP 403 errors.
Can I inject global variables into the HTML page?
Yes. Use the injection configuration block to inject JavaScript or CSS into the HTML entry page. Injection supports three positions:
| Position | Description |
|---|---|
injection.head | Injects into the <head> tag. Typically used for CSS styles or meta tags |
injection.body.first | Injects at the beginning of the <body> tag |
injection.body.last | Injects at the end of the <body> tag |
Example configuration:
grayKey: userid
rules:
- name: inner-user
grayKeyValue:
- '00000001'
- '00000005'
baseDeployment:
version: base
grayDeployments:
- name: beta-user
version: gray
enabled: true
weight: 80
injection:
head:
- <script>console.log('Header')</script>
body:
first:
- <script>console.log('hello world before')</script>
- <script>console.log('hello world before1')</script>
last:
- <script>console.log('hello world after')</script>
- <script>console.log('hello world after2')</script>This example also demonstrates weight-based canary release. With weight: 80, 80% of non-rule-matched traffic goes to the canary version, and 20% goes to the base version.
When does the canary version take effect for a user?
The canary version takes effect on the next full page load, not in real time. If user A is on version 0.0.1 and you publish version 0.0.2 with a canary rule that matches user A, the new version appears only after user A refreshes or re-loads the page.
This behavior is by design for two reasons:
User experience: Switching versions mid-session could break in-progress interactions, such as making a button disappear while a user is clicking it.
Architecture decoupling: Real-time version switching would require the backend to dynamically control frontend versions, coupling frontend and backend releases and preventing CDN caching.
When does a page refresh occur?
A page refresh typically occurs when:
A session expires and the user re-authenticates.
The user navigates to the login page.
To load the latest canary configuration on login, redirect with a full page navigation:
async function handleLogin(values: LoginParams) {
try {
const result = await login(values);
if (result.success) {
message.success('Logon succeeded.');
await updateUserInfo();
const urlParams = new URL(window.location.href).searchParams;
// Full page redirect ensures the canary version is loaded
window.location.href = `${urlParams.get('redirect') || '/'}`;
return;
}
console.log(result);
setLoginResult(result);
} catch (error) {
message.error('Logon failed. Try again.');
console.log(error);
}
}The key line is window.location.href = .... This triggers a full page navigation, forcing the browser to request the page from the gateway. The frontend-gray plug-in then evaluates the canary rules and serves the correct version.