gateway与nacos结合实现灰度发布

1.引入jar包

<dependencies>
    <!--nacos的服务发现-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--用redis实现限流-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>
    <!--springboot端点-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

注意这里的springboot与springcloud的版本号:我遇到的坑是,我一开始使用的是springboot2.0.X的,springcloud用的F版本的,gateway好像不能很好的支持,

LoadBalancerClientFilter这个类没有choose这个方法,估计是我技术不行,没研究透,不过我把版本升上去,spingboot2.2.3.RELEASE  springcloud Hoxton.RELEASE,就行了

2.编写程序

建个实体类:用于接收nacos的每个服务的元数据

@Data
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class GrayscaleProperties {
    private String version;
    private String serverName;
    private String serverGroup;
    private String active;
    private double weight = 1.0D;
}
@Slf4j
@Component
public class GatewayLoadBalancerClientFilter extends LoadBalancerClientFilter {


    public GatewayLoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
        super(loadBalancer, properties);
    }
    @Override
    protected ServiceInstance choose(ServerWebExchange exchange) {

        if (this.loadBalancer instanceof RibbonLoadBalancerClient) {
            RibbonLoadBalancerClient client = (RibbonLoadBalancerClient) this.loadBalancer;
            HttpHeaders headers = exchange.getRequest().getHeaders();
            String version = headers.getFirst(GrayscaleConstant.GRAYSCALE_VERSION);
            String serviceId = ((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost();
            GrayscaleProperties build = GrayscaleProperties.builder().version( version ).serverName( serviceId ).build();
            //这里使用服务ID 和 version 做为选择服务实例的key
            //TODO 这里也可以根据实际业务情况做自己的对象封装
            return client.choose(serviceId,build);
        }
        return super.choose(exchange);
    }
}
@Configuration
public class GrayGatewayReactiveLoadBalancerClientAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean({GatewayLoadBalancerClientFilter.class})
    public GatewayLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
        return new GatewayLoadBalancerClientFilter(loadBalancer, properties);
    }

    @Bean
    @ConditionalOnMissingBean({GrayscaleLoadBalancerRule.class})
    public GrayscaleLoadBalancerRule GrayscaleLoadBalancerRule() {
        return new GrayscaleLoadBalancerRule();
    }
}

前段要在head里放个versionzi端,naocs的服务元数据里也要放version字段。getway的灰度发布就结束了

经验分享 程序员 微信小程序 职场和发展