×
Community Blog Application of the WASM Plug-in in End-to-End Canary Release

Application of the WASM Plug-in in End-to-End Canary Release

MSE provides a set of mature functions in the end-to-end canary release scenario of microservices and supports canary routing policies of content rules and percentage rules.

By Shimian

According to research data, around 70% of production failures are caused by changes. To mitigate risks during the change process, we want to use a small portion of targeted traffic to verify that the newly released application is functioning normally during deployment. Even if issues arise with the new version, they can be detected in time to minimize impact and ensure overall stability. This is the capability of end-to-end canary release under microservices architecture.

Microservices Engine (MSE) offers a suite of mature and out-of-the-box capabilities for end-to-end canary release scenarios in a microservices environment.

1

With the deepening transformation of enterprise microservices, there are more demands for microservices governance scenarios and applications, such as end-to-end canary release. By default, MSE supports canary routing policies based on content rules and percentage rules. According to canary contents, parameters such as header and params, and multiple matching policies such as exact, prefix, and regular expression are all supported. This meets the requirements of common end-to-end canary scenarios.

However, how can we handle it if the policies provided by MSE cannot meet the requirements in complex scenarios?

Next, we will discuss several complex but reasonable canary requirements.

Complex but Reasonable Canary Requirements

In fact, there are many other reasonable demands for end-to-end canary release, for example:

  1. We hope that the random percentage can be adjusted according to the parameter characteristics, so that for each user, the canary is fixed, and the experience is consistent for multiple calls.
  2. The traffic from the mobile phone client has the feature of version, and the traffic from the web page has the feature of tag. We expect the traffic that meets either condition to enter the canary environment, that is, the mode in which the traffic condition matches "or".
  3. The traffic from production is indeed relatively large, so we hope that the first batch of canary traffic can control the canary demand to 1 ‰ of the overall traffic.
  4. We expect that the canary demands can be parsed based on the traffic Body parameter.

Faced with a series of complex but reasonable demands with customized requirements, it is difficult for the product level to fully support them. These demands are very common in practical production, which is faced by enterprise customers. However, it seems that the configuration solution of the current MSE console does not perfectly cope with these diverse practical scenarios. After all, when we turn our attention to the production practices of different enterprise customers, we will find that the change and diversity of complex scenarios will only become more significant. So, how can we effectively meet the demands of end-to-end canary release in complex environments?

Cloud-native Gateway Wasm Plug-in

What is Wasm? Wasm (WebAssembly) is a portable, high-performance binary instruction set that enables code to run in a web browser. Envoy leverages Wasm as a plugin extension mechanism, allowing developers to create custom feature extensions tailored to specific needs.

2

The extension mechanism of the cloud-native gateway Wasm plug-in works as follows:

  1. MSE cloud-native gateway provides a plug-in marketplace so that we can write custom Wasm plug-ins to meet the demands of various extensions, such as request/response conversion, filters, and authentication. At the same time, we can also write Wasm plug-in support, such as Go, Rust, class JS, and lua.
  2. We only need to upload the compiled Wasm file to the plug-in marketplace through a custom plug-in, and the MSE cloud-native gateway will load it to Envoy.
  3. When the cloud-native gateway processes network traffic, according to the configuration, it will pass the traffic to the appropriate Wasm plug-in for processing, that is, Custom Filters in the above figure. Wasm plug-ins can read and modify request/response data, execute custom logic, and pass traffic to the next plug-in or final destination.

The MSE plug-in marketplace also provides some official platform plug-ins such as default authentication, throttling, and security protection to improve the security and stability of gateways. It also supports multi-language custom extensions to meet the requirements for custom traffic governance on gateways.

The advantages of the MSE Wasm plug-in extension mechanism include:

  1. It supports multi-language extensions by Wasm features, thus providing flexibility and scalability, so we can use Wasm plug-ins for writing and development to meet specific business requirements.
  2. The gateway Wasm plug-in is 100% compatible with the open-source Envoy and will not be locked.
  3. It provides a plug-in marketplace, and the secondary extension functions of the gateway are provided to users on demand through plug-ins.
  4. The plug-in uses the hot update mechanism and is executed in a sandbox, which does not affect the stability of the gateway itself.

With its unique lightweight and high performance features, the Wasm plug-in brings innovative scalability to cloud-native gateways without significant performance overhead. The Wasm plug-in runs in a sandbox environment and provides a secure and controllable way to deploy custom logic. This not only ensures the flexibility and scalability of the gateway but also ensures minimal impact on the overall performance.

It seems that the MSE cloud-native gateway Wasm plug-in is indeed an elegant and convenient way to meet various end-to-end canary requirements. Next, I will write the Wasm plug-in to implement end-to-end canary release in complex conditions.

Use the Wasm Plug-in to Implement Parameter Ratios

As mentioned above, the Wasm plug-in supports multi-language extensions, so we can choose the language that we are good at for development. This article uses the Go language as an example.

The cloud-native gateway provides wrapper packages and related APIs for us to quickly write Wasm plug-ins.

1. The cloud-native gateway configures canary routing based on x-mse-tag. For more information, see Implement an End-to-End Canary Release by Using MSE Cloud-native Gateways [1].

Configure the service swimlanes as follows:

3

Configure the cloud-native gateway route as follows:

4

After we create a canary lane, all the requests with x-mse-tag=gray in the header will be considered canary traffic, and they will first go to the canary environment in subsequent traces. Therefore, in the Wasm plug-in, we can perform any custom calculation and matching on the traffic. As long as it meets canary conditions, we can add an identifier named "x-mse-tag" with a value of "gray" to the request header. In this way, we can label and identify the canary traffic.

2. Define the plug-in extension configuration.

type ParamsRandomConfig struct {
    # The switch of parameter ratio function
    paramsRandomEnable    bool
    # The value of the header that the parameter ratio is based on, for example, userId
  paramsRandomHeaderKey string
    # Percentage value of the parameter ratio,
    paramsPercentageRatio     int64
}

3. Parse the extension parameters of the plug-in. The YAML configuration that you enter in the plug-in configuration in the console is automatically converted to JSON, so it can parse the configuration directly from the JSON parameter.

// The YAML configuration that you enter in the plug-in configuration in the console is automatically converted to JSON, so it can parse the configuration directly from the JSON parameter.
func parseConfig(json gjson.Result, config *MyConfig, log wrapper.Log) error {
  // Parse the configuration and update it to the config file.
  config.paramsRandomEnable = json.Get("paramsRandomEnable").Bool()
  config.paramsRandomHeaderKey = json.Get("paramsRandomHeaderKey").String()
  config.paramsPercentageRatio = json.Get("paramsPercentageRatio").Int()

  return nil
}

4. Request processing Filter compilation.

func onHttpRequestHeaders(ctx wrapper.HttpContext, config MyConfig, log wrapper.Log) types.Action {
  if config.paramsRandomEnable {
    randomHeaderValue, err := proxywasm.GetHttpRequestHeader(config.paramsRandomHeaderKey)
    if err != nil {
      proxywasm.LogErrorf("get header enhance error: %v", err)
      return types.ActionContinue
    }

    // Obtain the hash of the target parameter value for percentage calculation.
    hash := sha256.Sum256([]byte(randomHeaderValue))
    hashInt := new(big.Int)
    hashInt.SetBytes(hash[:])

    modulo := new(big.Int).Mod(hashInt, big.NewInt(100))
    result := modulo.Cmp(big.NewInt(config.paramsPercentageRatio))
    if result <= 0 {
      // Write x-mse-tag=gray to indicate that the request traffic is marked as gray, and the node in the gray environment will be preferentially used in subsequent traces.
      // If the corresponding application does not have a gray environment, it will fall back to the baseline environment.
      proxywasm.AddHttpRequestHeader("x-mse-tag", "gray")
    } else {
      // The traffic that does not meet the canary conditions.
      proxywasm.LogInfof("set header false value: %s, hash: %s", randomHeaderValue, hashInt)
    }
  }
  return types.ActionContinue
}

5. Compile and generate Wasm files.

Run the following command to compile the Wasm file.

go mod tidy
tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags='custommalloc nottinygc_finalizer' ./main.go

If the compilation is successful, the file main.wasm will be created in the current directory. The main.wasm file is used in the example for local debugging in this topic.

If you use a custom plug-in that is created on the Plug-in Marketplace page in the MSE console, you can directly upload this file.

6. Configure the parameters and verify the parameter ratio function.

5

As shown in the above figure, we specify userId in the header as the parameter that the percentage is based on, and configure the ratio value of the 10% canary traffic. After we click Save, the configuration takes effect in real time.

In the request process, the header of userId=1 always goes to the canary environment, and the request of userId=11 always goes to the baseline environment.

7. Observe plug-in logs.

So far, we have implemented the parameter ratio requirements based on specific headers by writing the Wasm plug-in.

Summary

We can use the Wasm plug-in to meet various requirements of end-to-end canary release, including but not limited to the following aspects:

Canary Release Based on User ID

Requests from specific users can be routed to the corresponding canary environment based on the user's identity, role, and permissions to implement end-to-end canary releases for individual users.

Canary Release Based on Geographic Location

Requests can be routed to the canary environment of a specific region based on the user's geographical location information to meet the canary requirements of a specific region.

Canary Release Based on Traffic Ratio

Requests can be routed to different canary environments based on the traffic ratio to implement end-to-end canary release with proportionally distributed traffic.

Canary Release Based on Complex Attributes of Request Packages

Requests can be routed to the corresponding canary environment by determining whether specific conditions are met based on the request attributes, such as the request header, request body, and query parameters.

Because of its great adaptability, the Wasm plug-in can be tailored to meet different requirements for end-to-end canary release. This provides unlimited possibilities for customized business scenarios, enabling canary testing and release to be performed flexibly based on unique business requirements. Especially for compute-intensive and stateless tasks, such as authentication, encryption and obfuscation of requests/responses, and content transformation, it is ideal to deploy the logic at the gateway layer. It not only keeps the system simple and flexible but also ensures low performance loss of core gateway functions, which provides significant benefits in optimizing resource usage and maintaining service quality.

At present, the MSE Wasm plug-in supports Redis access. Of course, we should use the Wasm plug-in based on the use case. If the logic needs to connect to the database or multi-threaded processing, it is not suitable to be made into a gateway plug-in. Currently, Wasm plug-in does not support these capabilities.

Reference

[1] Implement an End-to-End Canary Release by Using MSE Cloud-native Gateways
https://www.alibabacloud.com/help/en/mse/user-guide/implement-an-end-to-end-canary-release-by-using-mse-cloud-native-gateways
[2] Plug-in Development: Microservices Engine (MSE)
https://www.alibabacloud.com/help/en/mse/user-guide/14/

0 0 0
Share on

Alibaba Cloud Native

206 posts | 12 followers

You may also like

Comments

Alibaba Cloud Native

206 posts | 12 followers

Related Products