Ribbon配置IRule,导致请求路由错乱或No instances available for ***

在SpringBoot工程中,错误地以@Bean方式配置IRule(如RandomRule)会导致所有服务共享同一实例,进而影响负载均衡,使服务请求被错误路由,当服务没有可用实例时,会出现Noinstancesavailable异常。正确的配置应通过ribbon.NFLoadBalancerRuleClassName属性,确保每个服务有自己的负载均衡规则实例。
摘要由CSDN通过智能技术生成

背景

技术线,springcloud,ribbon, eureka

错误配置方式


@Bean
public IRule myRule() {
     // 定义为随机
     return new RandomRule();
}

在springBoot工程中加入如上配置,有多个下游service服务的时候。通过org.springframework.web.client.RestTemplate调用下游服务时。com.netflix.loadbalancer.ILoadBalancer#chooseServer就无法发现服务地址,从而会报No instances available for ***异常。

原因分析

netflix的spring ApplicationContext容器是每个远程service对应一个,ApplicationContext维护在如下map中:

org.springframework.cloud.context.named.NamedContextFactory#contexts

private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();

而ILoadBalancer,IRule 实例维护,是每个远程service对应的ApplicationContext管理各自的实例。

那么在springBoot工程中@Bean方式申明IRule实例,因为此实例会在父springContext中实例化,最后导致所有远程service对应的ApplicationContext都只使用此一个IRule.

而IRule会关联ILoadBalancer执行路由chooseServer操作。从而导致有的服务就会服务A的请求会被路由到服务B上去。(如此便导致了路由错乱)

假如服务B没有可用地址,那么就会导致No instances available for B错误。

正确配置方式

ribbon:
  NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
这种方式配置的IRule,可以保证每个远程service对应的ApplicationContext各自实例化自己的RandomRule。

参考:

Ribbon规则IRule调整遇到的坑 - 简书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值