微服务:Eureka,Ribbon,Hystrix( 七 )

IRule 的子实现类:
IRule <--实现-- AbstractLoadBalancerRule?AbstractLoadBalancerRule <--继承-- [RandomRule, RoundRobinRule, ClientConfigEnabledRoundRobinRule, RetryRule]?RoundRobinRule <--继承-- WeightedResponseTimeRule ?ClientConfigEnabledRoundRobinRule <--继承-- [PredicateBasedRule, BestAvailableRule]?PredicateBasedRule <--继承-- [AvailabilityFilteringRule, ZoneAvoidanceRule]

  • RoundRobinRule - 轮询策略:
默认超过 10 次获取到的 server 都不可用,会返回一个空的 server 。
  • RandomRule - 随机策略:
如果随机到的 server 为 null 或者不可用的话,会 while 不停的循环选取 。
  • RetryRule - 重试策略:
一定时限内循环重试 。默认继承 RoundRobinRule,也支持自定义注入,RetryRule 会在每次选取之后,对选举的 server 进行判断,是否为 null,是否 alive,并且在 500ms 内会不停的选取判断 。而 RoundRobinRule 失效的策略是超过 10 次,RandomRule 是没有失效时间的概念,只要 serverList 没都挂 。
  • BestAvailableRule - 最小连接数策略:
遍历 serverList,选取出可用的且连接数最小的一个 server 。该算法里面有一个 LoadBalancerStats 的成员变量,会存储所有 server 的运行状况和连接数 。如果选取到的 server 为 null,那么会调用 RoundRobinRule 重新选取 。
  • AvailabilityFilteringRule - 可用过滤策略:
扩展了轮询策略,会先通过默认的轮询选取一个 server,再去判断该 server 是否超时可用,当前连接数是否超限,都成功再返回 。
  • ZoneAvoidanceRule - 区域权衡策略(默认策略):
扩展了轮询策略,继承了 2 个过滤器:ZoneAvoidancePredicate 和 AvailabilityPredicate,除了过滤超时和链接数过多的 server,还会过滤掉不符合要求的 zone 区域里面的所有节点,在一个区域/机房内的服务实例中轮询;先过滤再轮询 。
修改负载均衡策略:
# 针对的被调用方微服务名称,不加就是全局生效lagou-service-product:ribbon:# 请求连接超时时间ConnectTimeout: 2000# 请求处理超时时间ReadTimeout: 15000# 对所有操作都进行重试OkToRetryOnAllOperations: true## 根据如上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由 MaxAutoRetries 配置),## 如果不行,就换一个实例进行访问,如果还不行,再换一次实例访问(更换次数由 MaxAutoRetriesNextServer 配置),## 如果依然不行,返回失败信息 。# 对当前选中实例重试次数,不包括第一次调用MaxAutoRetries: 2# 切换实例的重试次数MaxAutoRetriesNextServer: 2# 负载策略调整NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRuleRibbon 核心源码剖析Ribbon 工作原理:
Actor ----> 拦截器 ----> 负载均衡算法(Ribbon)----> 目标微服务Ribbon:按照一定算法选取服务实例SpringCloud 充分利用了 SpringBoot 的自动装配特点 。
引入的 Maven 依赖 --> spring-cloud-commons-2.1.0.RELEASE.jar --> META-INF --> spring.factories 配置文件:
# AutoConfigurationorg.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.cloud.client.CommonsClientAutoConfiguration,org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration,org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration,org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,...点击配置文件中的 LoadBalancerAutoConfiguration 跳转到其源码文件:
@Configuration@ConditionalOnClass(RestTemplate.class)@ConditionalOnBean(LoadBalancerClient.class)@EnableConfigurationProperties(LoadBalancerRetryProperties.class)public class LoadBalancerAutoConfiguration {@LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList();... @Configuration @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") static class LoadBalancerInterceptorConfig {@Beanpublic LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient,LoadBalancerRequestFactory requestFactory) {return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);}@Bean@ConditionalOnMissingBeanpublic RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {return restTemplate -> {List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());list.add(loadBalancerInterceptor);restTemplate.setInterceptors(list);};} }...}


推荐阅读