【Loadbalancer】解决withHints()配置不生效问题

解决办法

配置类

官方示例中提到,要使用hint可以采用下面的方式开启:

java 复制代码
public class CustomLoadBalancerConfiguration {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
            ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
                    .withDiscoveryClient()
                    .withHints()
                    .withCaching()
                    .build(context);
    }
}

但是我按照上面的配置后,hint不会生效,debug时不会进入到filteredByHint(),在执行完cache相关的类后直接返回。

因此,关掉cache使hint生效,即:

java 复制代码
public class CustomLoadBalancerConfiguration {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
            ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
                    .withDiscoveryClient()
                    .withHints()
                    .build(context);
    }
}

此外,如果同时使用了基于区间的过滤,需要注意二者的顺序:

java 复制代码
public class CustomLoadBalancerConfiguration {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
            ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
                    .withDiscoveryClient()
                    .withZonePreference()
                    .withHints()
                    .build(context);
    }
}

原因

有个choose()方法,返回时,调用了ServiceInstanceListSupplier接口的default Flux<List<ServiceInstance>> get(Request request)方法。

default Flux<List<ServiceInstance>> get(Request request)方法里面调用了一个父类Supplierget()方法

java 复制代码
// ServiceInstanceListSupplier
default Flux<List<ServiceInstance>> get(Request request) {
	return get();
}

而这个接口有好几个实现类,其中包括ZonePreferenceServiceInstanceListSupplierCachingServiceInstanceListSupplierHintBasedServiceInstanceListSupplier这三个类:


withCaching()

会先进入CachingServiceInstanceListSupplier类中,执行它的get()方法,直接返回一个Flux<List<ServiceInstance>>,然后直接进行response。

java 复制代码
// CachingServiceInstanceListSupplier
@Override
public Flux<List<ServiceInstance>> get() {
	return serviceInstances;
}

如果没有withCaching()

则会调用HintBasedServiceInstanceListSupplierget()方法,在HintBasedServiceInstanceListSupplier中首先会调用ServiceInstanceListSupplierget(request)方法(上面的get()方法)

java 复制代码
// HintBasedServiceInstanceListSupplier
@Override
public Flux<List<ServiceInstance>> get(Request request) {
	return delegate.get(request).map(instances -> filteredByHint(instances, getHint(request.getContext())));
}

这次get()调用的实现类是ZonePreferenceServiceInstanceListSupplier,在里面进行基于zone过滤

java 复制代码
// ZonePreferenceServiceInstanceListSupplier
@Override
public Flux<List<ServiceInstance>> get() {
	return getDelegate().get().map(this::filteredByZone);
}

总结:

java 复制代码
choose(){
	HintBasedServiceInstanceListSupplier.get(){
		ZonePreferenceServiceInstanceListSupplier.getDelegate().get().map(this::filteredByZone);
	}
}

application.yml文件

消费者

yaml 复制代码
server:
  port: 8080

spring:
  application:
    name: consumer-01

  cloud:
    nacos:
      server-addr: localhost:8848

    loadbalancer:
      ribbon:
        enabled: false
      enabled: true
      configurations: zone-preference
      zone: myzone
      hint:
        default: myhint

生产者

yaml 复制代码
server:
  port: 8081

spring:
  application:
    name: provider-01
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        metadata:
          zone: myzone
          hint: myhint
    loadbalancer:
      ribbon:
        enabled: false
      enabled: true
      configurations: zone-preference

相关推荐
David爱编程10 分钟前
Java 守护线程 vs 用户线程:一文彻底讲透区别与应用
java·后端
即将进化成人机36 分钟前
Maven架构的依赖管理和项目构建
java·架构·maven
qianmoq1 小时前
第03章:无限流:generate()和iterate()的神奇用法
java
whitepure1 小时前
万字详解JVM
java·jvm·后端
我崽不熬夜1 小时前
Java的条件语句与循环语句:如何高效编写你的程序逻辑?
java·后端·java ee
我崽不熬夜2 小时前
Java中的String、StringBuilder、StringBuffer:究竟该选哪个?
java·后端·java ee
bing.shao2 小时前
gRPC 选型 etcd 的核心优势分析
数据库·微服务·云原生·golang·etcd
草明2 小时前
docker stats 增加一列容器名称的显示
java·开发语言·docker
期待のcode2 小时前
Maven的概念与Maven项目的创建
java·maven
我崽不熬夜2 小时前
Java中的基本数据类型和包装类:你了解它们的区别吗?
java·后端·java ee