承接之前一篇文章“feign,ribbon和eureka的一些理解”
里面提到“比如多版本发布的时候,怎么过滤出符合要求的版本?”这个问题;
之前我只是找到了一个地方,后来发现后别扭;最近发现
Ribbon是可以实现自定义过滤器的;
-
首先是 默认的实现:
2Spring Cloud Netflix默认情况下为Ribbon提供以下bean: (在RibbonClientConfiguration类里面可以看到)
格式:(BeanType beanName:ClassName)
IClientConfig ribbonClientConfig:DefaultClientConfigImpl
IRule ribbonRule:ZoneAvoidanceRule
IPing ribbonPing:NoOpPing
ServerList ribbonServerList:ConfigurationBasedServerList
ServerListFilter ribbonServerListFilter:ZonePreferenceServerListFilter
ILoadBalancer ribbonLoadBalancer:ZoneAwareLoadBalancer
ServerListUpdater ribbonServerListUpdater:PollingServerListUpdater -
其中ServerListFilter ribbonServerListFilter:ZonePreferenceServerListFilter;
也就是ZonePreferenceServerListFilter是默认的bean;
同时,Spring Cloud可以让你自己完全控制Ribbon客户端,通过用@RibbonClient来声明额外的配置;
比如:
自定义一个过滤器:
GrayFilter 可以类似ZonePreferenceServerListFilter一样继承ZoneAffinityServerListFilter ;
然后再添加你自己的逻辑,一般是在getFilteredListOfServers()方法里;
当然,GrayFilter只要是ServerListFilter 里实现类就可以了
(不过测试发现这里的Filter是类似定时器任务一样过滤的,需要根据具体情况来看是否适用;对于每次请求都需要过滤的需求,我的一个解决方法是重载IRule ribbonRule)
其他的bean亦可以通过类似的方式进行自定义。
05-30更新:
卧槽,有个史诗级bug;
当然实际上不算bug, 但是以上的修改和实际需求所要的业务逻辑不合;
@Configuration
public class TestRibbonConfiguration {
@Bean
@ConditionalOnBean(IClientConfig.class) //重点就是这个
IRule ribbonRule(IClientConfig config) {
ZoneAvoidanceRulerule = new ZoneAvoidanceRule();
rule.initWithNiwsConfig(config);
return rule;
}
如果是对于任意的${ribbon.client.name} 都要走自定义配置的Rule;
需要把参数IClientConfig config 加上,否则会有类似线程安全的错误;
(这是因为我本身的业务需求导致的 不合ribbon规范的 开发, 没办法,坑…)
写成IRule ribbonRule(IClientConfig config) 的话,会报错IClientConfig无法注入;
这个时候需要加上注解 @ConditionalOnBean(IClientConfig.class)
--另外,MyRibblonConfiguration 整个类都不要了, 因为这里定义的name是针对某些服务实例的,而我需要全部;
上面的的${ribbon.client.name} 对应的的就是MyRibblonConfiguration里的name;
(引入feign,eureka的话,)同时对应的就是@FeignClient(name="xxx") 这里的name