Cloud Native 10 min read

Implementing Gray Release with Spring Cloud LoadBalancer in Spring Cloud Gateway

This article explains how to achieve gray (canary) release across multiple environments by using Spring Cloud LoadBalancer in Spring Cloud Gateway, configuring service metadata and request headers to route traffic to specific instances, and provides two implementation approaches with full code examples.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Implementing Gray Release with Spring Cloud LoadBalancer in Spring Cloud Gateway

The author addresses a common issue where multiple environments share a registration center (Nacos) and service instances become indistinguishable, causing debugging requests to be routed to the wrong environment. The solution is to implement gray release using Spring Cloud LoadBalancer (SCL) in Spring Cloud Gateway.

Key concepts : gray (canary) release, service metadata versioning, custom load‑balancing rules, and request‑header based routing.

Implementation goals : ensure that during debugging, requests from a developer’s local instance reach only that instance.

Implementation steps :

Mark local service instances with a special metadata key, e.g., spring.cloud.nacos.discovery.metadata.version=dev , either via configuration or directly in Nacos.

Add a request header version=dev when calling the service, allowing the load balancer to select instances whose metadata matches this version.

The article then introduces Spring Cloud LoadBalancer (SCL) as the recommended load‑balancing component in Spring Cloud 2020, replacing Ribbon. Important points from the official documentation are highlighted:

SCL provides Round‑Robin and Random algorithms, defaulting to Round‑Robin.

Custom instance selection can be achieved by implementing ServiceInstanceListSupplier .

The LoadBalancerClient annotation specifies service‑level load‑balancing strategies.

Two implementation approaches :

Create a custom load‑balancing strategy ( VersionGrayLoadBalancer ) and bind it to a service via @LoadBalancerClient .

Implement a custom ServiceInstanceListSupplier ( VersionServiceInstanceListSupplier ) to filter instances based on the request header version.

Code snippets (kept intact):

<spring-boot.version>2.4.2</spring-boot.version>
<alibaba-cloud.version>2021.1</alibaba-cloud.version>
<springcloud.version>2020.0.0</springcloud.version>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
/**
 * Description:
 * Custom gray load balancer that matches request header "version" with service instance metadata "version".
 */
@Log4j2
public class VersionGrayLoadBalancer implements ReactorServiceInstanceLoadBalancer {
    // ... implementation omitted for brevity ...
}
public class VersionLoadBalancerConfiguration {
    @Bean
    ReactorLoadBalancer
versionGrayLoadBalancer(Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new VersionGrayLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }
}
public class VersionServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier {
    // ... filter instances by request header version ...
}

Finally, the author demonstrates testing steps: start multiple AccountService instances with version=dev metadata, send requests with the version header via Postman, and verify that the custom load‑balancing logic routes traffic as expected.

Conclusion : By extending SCL’s load‑balancing algorithm or customizing the service‑instance selection logic, a simple gray release mechanism can be achieved, and the approach can be adapted for other services.

Javamicroservicesgray releaseNacosSpring CloudSpring Cloud Gatewayloadbalancer
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.