Spring Cloud Gateway 自定义负载均衡器实现教程,指定服务自定义负载均衡器

望舒的头像
望舒
标签:
springcloudgateway自定义负载均衡器java

Spring Cloud Gateway 自定义负载均衡器实现教程,支持基于服务名(如 order-service)使用自定义轮询策略实现流量分发。支持 Spring Cloud LoadBalancer、Reactor 编程模型,适配 Nacos 等服务注册中心。适用于精细化流量控制、A/B 测试、自定义灰度发布等场景。


✅ 目标

为某个服务(如 "order-service")自定义负载均衡器逻辑(如:轮询、Hash、权重等),替换默认的 RoundRobinLoadBalancer


📦 配置类:LoadBalancerConfiguration

复制
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter({CachingServiceInstanceListSupplier.class, NacosServiceDiscovery.class})
public class LoadBalancerConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(LoadBalancerClientFactory.class)
    public ReactorServiceInstanceLoadBalancer customReactorServiceInstanceLoadBalancer(
            @NotNull Environment environment,
            @NotNull LoadBalancerClientFactory loadBalancerClientFactory
    ) {
        String serviceName = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        ObjectProvider<ServiceInstanceListSupplier> provider =
                loadBalancerClientFactory.getLazyProvider(serviceName, ServiceInstanceListSupplier.class);

        // 👇 自定义服务名判断
        if ("order-service".equals(serviceName)) {
            return new DemoLoadBalancer(serviceName, provider);
        }

        // 默认使用轮询负载均衡器
        return new RoundRobinLoadBalancer(provider, serviceName);
    }
}

⚙️ 自定义负载均衡器:DemoLoadBalancer

复制
public class DemoLoadBalancer implements ReactorServiceInstanceLoadBalancer {

    private final String serviceId;
    private final ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
    private final AtomicInteger position = new AtomicInteger(0); // 用于轮询选择

    public DemoLoadBalancer(String serviceId,
                            @NotNull ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }

    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = this.serviceInstanceListSupplierProvider
                .getIfAvailable(NoopServiceInstanceListSupplier::new);

        return supplier.get(request).next().map(serviceInstances -> {
            if (serviceInstances.isEmpty()) {
                return new EmptyResponse();
            }

            // 👇 只有一个实例,直接返回
            if (serviceInstances.size() == 1) {
                return new DefaultResponse(serviceInstances.getFirst());
            }

            // ✅ 简单轮询策略,实际应用可以根据一些关键参数作为依据进行分发
            int pos = Math.abs(this.position.incrementAndGet());
            ServiceInstance instance = serviceInstances.get(pos % serviceInstances.size());

            return new DefaultResponse(instance);
        });
    }
}

作者:https://blog.xn--rpv331d.com/望舒

链接:https://blog.xn--rpv331d.com/望舒/blog/70

转载注意保留文章出处...

‌​‌‌‌​​‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌‌​‌​​​‌‌​​‌​‌​‌‌​‌​‌‌‌‌‌‌​‌‌​‌‌​​​​​​​​‌​‌​​‌​‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌​​‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​​‌​​​​‌‌‌​​​​‌‌​​​‌​‌‌‌‌‌​‌‌‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌​​‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​​‌​​​​‌‌‌​​​​‌‌​​​‌​‌‌‌‌‌​‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌​‌‌​​​​‌​‌‌‌‌‌‌​‌​​‌‌‌‌​​‌​‌​​​​​​​​​​​​‌​‌​​‌​‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌​​‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​​‌​​​​‌‌‌​​​​‌‌​​​‌​‌‌‌‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌​​‌‌‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌​‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌​​‌​‌​​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​‌‌​‌​​‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​​‌​​​​‌‌‌​​​​‌‌​​​‌​‌‌‌‌‌​‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌‌‌‌​‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​‌‌‌‌​‌‌‌​‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌​​‌‌‌‌‌‌‌‌‌‌‌‌​‌‌​‌​‌‌‌‌‌‌‌‌​‌​‌​‌‌‌‌‌‌‌‌‌‌‌‌‌​‌​​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌‌‌‌‌​‌‌​‌‌​‌​‌‌‌​‌‌‌​​‌​‌​‌‌​‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌‌‌‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌​‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌‌‌‌​‌‌​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌‌‌​​​‌​‌​​​‌​‌‌‌‌‌​​​​​‌​​​‌​​‌‌‌‌‌‌​‌​​​​​​‌‌​​‌​‌‌‌‌​​‌‌‌‌​​​‌‌‌​‌​​​‌‌​​‌​​​​​‌‌‌​​​​‌‌​​​​​‌‌​‌‌​‌‌​‌‌‌‌​​​​​‌​‌‌‌‌​​​​​‌‌​​​‌‌‌‌​​‌​‌‌​​‌​​​​‌‌‌‌‌‌‌​​‌​‌​‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌‌‌‌‌​‌‌‌​​‌​‌​‌‌‌‌‌‌​‌‌‌‌​‌​‌‌‌‌​‌‌‌‌‌‌‌​‌‌​‌​​‌‌‌‌‌​‌‌‌​​‌​‌‌‌‌‌‌‌
0
0
0
13
No data