【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

相关推荐
^Moon^2 小时前
CycloneDDS:跨主机多进程通信全解析
c++·分布式·dds
小梁努力敲代码4 小时前
java数据结构--List的介绍
java·开发语言·数据结构
摸鱼的老谭5 小时前
构建Agent该选Python还是Java ?
java·python·agent
lang201509285 小时前
Spring Boot 官方文档精解:构建与依赖管理
java·spring boot·后端
夫唯不争,故无尤也5 小时前
Tomcat 启动后只显示 index.jsp,没有进入你的 Servlet 逻辑
java·servlet·tomcat
zz-zjx5 小时前
Tomcat核心组件全解析
java·tomcat
Deschen5 小时前
设计模式-外观模式
java·设计模式·外观模式
007php0076 小时前
百度面试题解析:微服务架构、Dubbo、Redis及其一致性问题(一)
redis·百度·docker·微服务·容器·职场和发展·架构
why技术6 小时前
从18w到1600w播放量,我的一点思考。
java·前端·后端
夫唯不争,故无尤也6 小时前
JavaWeb流式传输速查宝典
java·流式传输