You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免用负载均衡RestTemplate调用Eureka注册的DR状态服务实例

解决方案

针对Spring Boot 2.7.x版本,可通过给DR实例添加元数据标识+自定义负载均衡实例过滤规则的方式排除DR实例,无需硬编码IP,具体步骤如下:

1. 给服务B的DR实例添加元数据标记

在服务B的DR实例配置文件(application.yml或application.properties)中,添加Eureka元数据标识,用于区分DR实例和主实例:

eureka:
  instance:
    metadata-map:
      dr-instance: "true"

主实例无需配置该参数,或设置为dr-instance: "false"。

2. 自定义负载均衡实例过滤器

创建自定义过滤器类,过滤掉带有DR标识的服务实例:

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Flux;
import java.util.List;
import java.util.stream.Collectors;

public class DrInstanceExclusionFilter {

    public static ServiceInstanceListSupplier filterDrInstances(ServiceInstanceListSupplier supplier) {
        return new DelegatingServiceInstanceListSupplier(supplier) {
            @Override
            public Flux<List<ServiceInstance>> get() {
                return delegate.get().map(instances -> instances.stream()
                        // 过滤掉元数据中dr-instance为true的实例
                        .filter(instance -> !"true".equals(instance.getMetadata().get("dr-instance")))
                        .collect(Collectors.toList()));
            }
        };
    }
}

3. 配置服务B的负载均衡规则

创建专属配置类,将自定义过滤器应用到服务B的负载均衡逻辑中(注意:该配置类不要放在启动类的扫描包下,避免全局生效):

import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class ServiceBLoadBalancerConfig {

    @Bean
    public ServiceInstanceListSupplier serviceInstanceListSupplier(Environment environment,
                                                                   LoadBalancerClientFactory loadBalancerClientFactory) {
        ServiceInstanceListSupplier defaultSupplier = loadBalancerClientFactory.getLazyProvider(environment,
                ServiceInstanceListSupplier.class);
        return DrInstanceExclusionFilter.filterDrInstances(defaultSupplier);
    }
}

4. 绑定服务B与自定义配置

在服务A的启动类上,通过@LoadBalancerClients注解指定服务B使用上述自定义配置:

import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@LoadBalancerClients(value = {
        @LoadBalancerClient(name = "service-b", configuration = ServiceBLoadBalancerConfig.class)
})
public class ServiceAApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceAApplication.class, args);
    }
}

原理说明

服务B的DR实例注册到Eureka时会携带dr-instance=true的元数据,服务A的负载均衡组件在选择实例前,会通过自定义过滤器过滤掉带有该标识的实例,从而避免请求被转发到DR实例。当DR与主实例切换时,只需确保新实例的元数据配置正确,就能自动适配,无需修改服务A的代码或配置。

内容的提问来源于stack exchange,提问作者krishna thota

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:34:59