Deploying a new application version to all instances at once risks widespread failures. A canary release lets you deploy changes to a small instance group first, verify the update with a controlled percentage of traffic, and then roll out to the remaining instances in phases. This topic walks you through the canary release workflow using the Enterprise Distributed Application Service (EDAS) SDK for Java.
How a canary release works
A canary release through the EDAS API follows three stages:
Deploy to the canary group -- Call
DeployApplicationto deploy the new version to a specific instance group with a traffic control strategy.Get the phase IDs -- Call
GetChangeOrderInfoto retrieve thePipelineIdfor each release phase.Trigger the remaining phases -- Call
ContinuePipelinewith each subsequentPipelineIdto advance through the remaining phases.
DeployApplication GetChangeOrderInfo ContinuePipeline
(canary group + traffic) -> (get pipeline IDs) -> (trigger next phase) -> ... -> DonePrerequisites
Before you begin, make sure that you have:
EDAS SDK for Java installed. For more information, see "Use EDAS SDK for Java to call EDAS API"
The region ID where the application runs. In this example:
cn-hangzhouA microservice namespace. For more information, see Create a microservice namespace. If a namespace already exists, call ListUserDefineRegion and get the namespace ID from the
RegionIdparameterAn application created in an ECS cluster. For more information, see Create an application in an ECS cluster by calling an API operation. If the application already exists, call ListApplication and get the application ID from the
AppIdparameter. In this example:6bbc57a2-a017-4bec-b521-49a15bd3****The JAR or WAR deployment package uploaded to a destination address. In this example, the Object Storage Service (OSS) address is
https:doc***.oss-cn-hangzhou.aliyuncs.com/sc-****-D-0.0.1-SNAPSHOT.jarThe instance group ID for the canary release. Call ListDeployGroup and get the group ID from the
GroupIdparameter. In this example:941be68c-4aac-48a1-88fe-c9ad1502****(HSF applications only) The EDAS Container version. Call ListBuildPack and get the version from the
ConfigIdparameter. In this example:57
Step 1: Deploy the application to the canary group
Call the DeployApplication operation to start a canary release. The following table describes the key parameters.
Key parameters
| Parameter | Method | Description | Example |
|---|---|---|---|
AppId | setAppId | Application ID. | 6bbc57a2-a017-4bec-b521-49a15bd3**** |
Desc | setDesc | Deployment description. | Canary release |
DeployType | setDeployType | Deployment method. Set to url. | url |
WarUrl | setWarUrl | URL of the JAR or WAR package. Store the package in OSS. | https:doc***.oss-cn-hangzhou.aliyuncs.com/sc-****-D-0.0.1-SNAPSHOT.jar |
PackageVersion | setPackageVersion | Package version. Up to 64 characters. A timestamp is recommended. | 20210417.173831 |
Gray | setGray | Set to true to enable canary release. | true |
TrafficControlStrategy | setTrafficControlStrategy | Traffic routing rules in JSON format. This example routes 50% of traffic to the canary group. | {"http":{"rules":[{"conditionType":"percent","percent":50}]}} |
GroupId | setGroupId | Instance group ID for the canary release. Set to all to deploy to all groups. | 941be68c-4aac-48a1-88fe-c9ad1502**** |
Batch | setBatch | Number of release phases for the remaining instances. A value greater than 1 triggers a phased release. | 2 |
ReleaseType | setReleaseType | Phased release mode. 0 = automatic (recommended), 1 = manual. | 1 |
BatchWaitTime | setBatchWaitTime | Wait time between phases, in minutes. Range: 0--5. Default: 0 (no wait). | 1 |
ComponentIds | setComponentIds | Application runtime component ID. Required for Tomcat and standard Java applications. 4 = Tomcat 7.0.91, 5 = OpenJDK 1.8.x, 6 = OpenJDK 1.7.x, 7 = Tomcat 8.5.42. | 5 |
BuildPackId | setBuildPackId | (HSF only) EDAS Container build package number. Get the value by calling ListBuildPack and reading the ConfigId parameter. | 57 |
For the full parameter list, see DeployApplication.
Sample code
The following example deploys a Spring Cloud or Dubbo application with a canary release. It routes 50% of traffic to the canary group and releases to the remaining instances in two manual phases.
To deploy a High-Speed Service Framework (HSF) application, add request.setBuildPackId(57) to specify the EDAS Container version. Get the version by calling the ListBuildPack operation and reading the ConfigId parameter.
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.edas.model.v20170801.DeployApplicationRequest;
import com.aliyuncs.edas.model.v20170801.DeployApplicationResponse;
public class DeployApplication {
public static void main(String[] args) {
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations.
// Using these credentials to perform operations in EDAS is a high-risk operation.
// We recommend that you use a RAM user to call API operations.
// To create a RAM user, log on to the RAM console.
// To prevent key leaks, do not save your AccessKey ID and AccessKey secret in the code.
// Read the AccessKey pair from environment variables.
String aliyun_user_ak = System.getenv("ACCESS_KEY_ID");
String aliyun_user_sk = System.getenv("ACCESS_KEY_SECRET");
String region_id = "cn-hangzhou";
DefaultProfile defaultProfile = DefaultProfile.getProfile(region_id, aliyun_user_ak, aliyun_user_sk);
DefaultAcsClient client = new DefaultAcsClient(defaultProfile);
DeployApplicationRequest request = new DeployApplicationRequest();
// Application ID
request.setAppId("6bbc57a2-a017-4bec-b521-49a15bd3****");
// Deployment description
request.setDesc("Canary release");
// Deployment method: url
request.setDeployType("url");
// URL of the deployment package (JAR or WAR) in OSS
request.setWarUrl("https:doc***.oss-cn-hangzhou.aliyuncs.com/sc-****-D-0.0.1-SNAPSHOT.jar");
// Package version (timestamp recommended, up to 64 characters)
request.setPackageVersion("20210417.173831");
// Enable canary release
request.setGray(true);
// Route 50% of traffic to the canary group
request.setTrafficControlStrategy("{\"http\":{\"rules\":[{\"conditionType\":\"percent\",\"percent\":50}]}}");
// Instance group ID for the canary release
request.setGroupId("941be68c-4aac-48a1-88fe-c9ad1502****");
// Release to remaining instances in 2 phases
request.setBatch(2);
// Manual phased release (0 = automatic, 1 = manual)
request.setReleaseType((long) 1);
// Wait 1 minute between phases (range: 0-5)
request.setBatchWaitTime(1);
// Application component: 5 = OpenJDK 1.8.x
request.setComponentIds("5");
try {
DeployApplicationResponse response = client.getAcsResponse(request);
System.out.println("Message=" + response.getMessage() + "\nChangeOrderId=" + response.getChangeOrderId());
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}Expected output:
Message=success
ChangeOrderId=4a3329de-2495-4c51-be33-f69ff264****Save the ChangeOrderId value. You need it in the next step to query the release phases.
Step 2: Get the phase IDs
Call the GetChangeOrderInfo operation with the ChangeOrderId from Step 1 to retrieve the PipelineId for each release phase.
Sample response (partial):
{
"Message": "success",
"RequestId": "0EB98A7D-50CE-4F5F-855D-70BAF61DFB38",
"Code": 200,
"changeOrderInfo": {
"Status": 8,
"Desc": "Canary release",
"PipelineInfoList": {
"PipelineInfo": [
{
"PipelineId": "09e7d9aa-e79d-49ef-99b9-5405532d****"
},
{
"PipelineId": "1ea53844-2c60-46f1-b46d-df3b34d0****"
},
{
"PipelineId": "d99da075-b87d-4fe7-bbb6-ae1c6c26****"
}
]
}
}
}In this example, three phase IDs are returned because the release has three stages:
| Phase | PipelineId | Action |
|---|---|---|
| 1 | 09e7d9aa-...**** | Canary group deployment (already in progress) |
| 2 | 1ea53844-...**** | First batch of remaining instances -- trigger manually |
| 3 | d99da075-...**** | Second batch of remaining instances -- trigger manually |
A Status value of 8 means the release is waiting for you to manually trigger the next phase.
Step 3: Trigger the remaining phases
Before you trigger the remaining phases, verify the update on the canary group instances. If the verification is successful, call the ContinuePipeline operation with the second PipelineId to release the application to the first batch of remaining instances.
Sample response:
{
"Message": "success",
"RequestId": "B8ECF6F7-672D-40E9-91DD-1C33F06D4FD8",
"Code": 200
}After the first batch completes, call ContinuePipeline again with the third PipelineId to release to the second batch.
Sample response:
{
"Message": "success",
"RequestId": "7BB4F043-7C28-4A0E-B6A5-D4023EB24388",
"Code": 200
}If you configured more than two phases for the remaining instances, repeat this step with each subsequent PipelineId.
Verify the result
Call the GetChangeOrderInfo operation again to check the release status. The changeOrderInfo.Status field indicates the current state:
| Status | Description |
|---|---|
0 | Ready |
1 | In progress |
2 | Succeeded |
3 | Failed |
6 | Terminated |
8 | Waiting for manual trigger (manual phased release) |
9 | Waiting for automatic trigger (automatic phased release) |
10 | Failed due to a system exception |
A Status value of 2 means the canary release completed successfully across all phases.
Sample response (partial):
{
"Message": "success",
"RequestId": "0EB98A7D-50CE-4F5F-855D-70BAF61DFB38",
"Code": 200,
"changeOrderInfo": {
"Status": 2,
"Desc": "Canary release",
"PipelineInfoList": {
"PipelineInfo": [
...
]
}
}
}If the status is 3 (Failed) or 10 (Failed due to a system exception), check the change order details in the PipelineInfoList to identify which phase failed. You can then fix the issue and start a new canary release.
Use automatic phased release (recommended)
The example above uses manual phased release (ReleaseType = 1), which requires you to call ContinuePipeline for each phase. For production environments, automatic phased release is recommended. Set the following parameters:
| Parameter | Value | Effect |
|---|---|---|
ReleaseType | 0 | The system triggers each subsequent phase automatically. |
BatchWaitTime | 0--5 | Wait time in minutes between phases. Use this interval to monitor the canary group before the next phase starts. |
With automatic phased release, you only need to call DeployApplication and then monitor the status with GetChangeOrderInfo. The system advances through each phase automatically after the specified wait time.
Related API operations
| Operation | Description |
|---|---|
| DeployApplication | Deploy or update an application. Full parameter reference. |
| GetChangeOrderInfo | Query change order details and release status. |
| ContinuePipeline | Trigger the next phase in a manual phased release. |
| ListDeployGroup | Query instance groups for an application. |