一. 现象
单独配置Ribbon配置, 如自定义Rule, 在配置类上@Configuration, 以及@Bean注解下, 必然会出现No qualifying bean of type ‘com.netflix.client.config.IClientConfig’ available 对多provider
服务调用时出现服务调用错误的提示: feign.FeignException$NotFound: status 404
二. 原因
Ribbon 配置类不能包含在主程序的@ComponentScan范围内
每一个ServiceId都有她专属的SpringContext
错误使用@Bean使得Rule被lb共享, 实际存在的配置对象只有一个
三. 修改方式
增加对服务provider的rule配置, 形如:
1 | base-service: |
或者以System.setProperty()方式在启动时设置
1 | System.setProperty("base-service" + ".ribbo.NFLoadBalancerRuleClassName",Rule.class.name()); |
四. 参考资料
https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html
https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers
补充
官网描述
在[Ribbon]官网中对于自定义指定Rule有如下描述:
这个自定义配置类不能放在@ComponentScan扫描的当前包以及子包中,
否则这个自定义的IRule会被所有的Ribbon客户端共享, 会导致一系列的问题.
常规处理方式
根据官网的描述, 不能放在当前包与子包中被扫到, 那么就可以新建一个独立的package, 在其中添加自定义的Rule规则类, 并在主启动类中, 添加@RibbonClient, 在其中指定configuration=自定义的规则类.class
PS:说实话这种方式很繁琐
推荐的方式
复习一下spring里面bean的注入方式, 一般默认使用都是singeton单例形式的, 也就是说正因为这个类是单例的, 才会导致各个Ribbon客户端在初始化时候获取到了同一个对象, 实际上还有prototype这一scope可以选择配置, 伪代码如下:
1 |
|
结论
至此, 这一问题顺利解决, 继续撸代码去.