分享

spring cloud ribbon学习五:Ribbon的实际使用(转载)

 Baruch 2018-05-09


https://www.jianshu.com/p/f86af82fa782

本篇文章是springcloud微服务实战书和工作实际使用的笔记。

配置详解

自动化配置

由于Ribbon中定义的每一个接口都有多种不同的策略实现,同时这些之间又有一定的依赖关系。

  • com.netflix.client.config.IClientConfigRibbon的客户端配置,默认采用com.netflix.client.config.DefaultClientConfigImpl实现。

  • com.netflix.loadbalancer.IRuleRibbon的负载均衡策略,默认采用com.netflix.loadbalancer.ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。

  • com.netflix.loadbalancer.IPingRibbon的实例检查策略,默认采用com.netflix.loadbalancer.NoOpPing实现,该检查策略是一个特殊的实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服务实例都是可用的。

  • com.netflix.loadbalancer.ServerList:服务实例清单的维护机制,默认采用com.netflix.loadbalancer.ConfigurationBasedServerList实现。

  • com.netflix.loadbalancer.ServerListFilter:服务实例清单过滤机制,默认采org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter,该策略能够优先过滤出与请求方处于同区域的服务实例。

  • com.netflix.loadbalancer.ILoadBalancer:负载均衡器,默认采用com.netflix.loadbalancer.ZoneAwareLoadBalancer实现,它具备了区域感知的能力。

上面的配置是在项目中没有引入spring Cloud Eureka,如果引入了EurekaRibbon依赖时,自动化配置会有一些不同。

通过自动化配置的实现,可以轻松的实现客户端的负载均衡。同时,针对一些个性化需求,我们可以方便的替换上面的这些默认实现,只需要在springboot应用中创建对应的实现实例就能覆盖这些默认的配置实现。

@Configuration
public class MyRibbonConfiguration {

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}

这样就会使用P使用了RandomRule实例替代了默认的com.netflix.loadbalancer.ZoneAvoidanceRule

也可以使用@RibbonClient注解实现更细粒度的客户端配置

Camden版本对RabbitClient配置的优化

上面的方式主要是通过独立创建一个Configuration类来定义IPingIRule等接口的具体实现Bean,然后通过RabbonClient时指定要使用的具体Configuration类来覆盖自动化配置的默认实现。在spring Cloud Ribbon Camden版本中对RibbonClient定义个性化配置的方法做出进一步优化。可以直接使用<clientName>.ribbon.<key>=<value>的形式进行配置。

user-service.ribbon.NFLoadBalancerPingClassName=com.netfix.loadbalancer.PingUrl

user-service是服务名,NFLoadBalancerPingClassName参数是用来指定IPing接口实现类。在Camden版本中,Spring Cloud Ribbon新增了一个org.springframework.cloud.netflix.ribbon.PropertiesFactory类动态的为RibbonClient创建这些接口实现。

PropertiesFactory类

Camden版本中我们可以通过配置的方式,更加方便的为RibbonClient指定ILoadBalancerIPingIRuleServerListServerListFilter的定制化实现。

参数配置

对于Ribbon的参数通常有二种方式:全局配置以及指定客户端配置

  • 全局配置的方式很简单
    只需要使用ribbon.<key>=<value>格式进行配置即可。其中,<key>代表了Ribbon客户端配置的参数名,<value>则代表了对应参数的值。比如,我们可以想下面这样配置Ribbon的超时时间
ribbon.ConnectTimeout=250

全局配置可以作为默认值进行设置,当指定客户端配置了相应的key的值时,将覆盖全局配置的内容

  • 指定客户端的配置方式
    <client>.ribbon.<key>=<value>的格式进行配置.<client>表示服务名,比如没有服务治理框架的时候(如Eureka),我们需要指定实例清单,可以指定服务名来做详细的配置,
user-service.ribbon.listOfServers=localhost:8080,localhost:8081,localhost:8082

对于Ribbon参数的key以及value类型的定义,可以通过查看com.netflix.client.config.CommonClientConfigKey类。

与Eureka结合

当在spring Cloud的应用同时引入Spring cloud RibbonSpring Cloud Eureka依赖时,会触发Eureka中实现的对Ribbon的自动化配置。这时的serverList的维护机制实现将被com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList的实例所覆盖,该实现会讲服务清单列表交给Eureka的服务治理机制来进行维护。IPing的实现将被
com.netflix.niws.loadbalancer.NIWSDiscoveryPing的实例所覆盖,该实例也将实例接口的任务交给了服务治理框架来进行维护。默认情况下,用于获取实例请求的ServerList接口实现将采用Spring Cloud Eureka中封装的
org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList,其目的是为了让实例维护策略更加通用,所以将使用物理元数据来进行负载均衡,而不是使用原生的AWS AMI元数据。

在与Spring cloud Eureka结合使用的时候,不需要再去指定类似的user-service.ribbon.listOfServers的参数来指定具体的服务实例清单,因为Eureka将会为我们维护所有服务的实例清单,而对于Ribbon的参数配置,我们依然可以采用之前的两种配置方式来实现。

此外,由于spring Cloud Ribbon默认实现了区域亲和策略,所以,可以通过Eureka实例的元数据配置来实现区域化的实例配置方案。比如可以将不同机房的实例配置成不同的区域值,作为跨区域的容器机制实现。而实现也非常简单,只需要服务实例的元数据中增加zone参数来指定自己所在的区域,比如:
eureka.instance.metadataMap.zone=shanghai
Spring Cloud Ribbon与Spring Cloud Eureka结合的工程中,我们可以通过参数禁用EurekaRibbon服务实例的维护实现。这时又需要自己去维护服务实例列表了。

ribbon.eureka.enabled=false.

重试机制

由于Spring Cloud Eureka实现的服务治理机制强调了cap原理的ap机制(即可用性和可靠性),与zookeeper这类强调cp(一致性,可靠性)服务质量框架最大的区别就是,Eureka为了实现更高的服务可用性,牺牲了一定的一致性,在极端情况下宁愿接受故障实例也不要丢弃"健康"实例。

比如说,当服务注册中心的网络发生故障断开时候,由于所有的服务实例无法维护续约心跳,在强调ap的服务治理中将会把所有服务实例剔除掉,而Eureka则会因为超过85%的实例丢失心跳而触发保护机制,注册中心将会保留此时的所有节点,以实现服务间依然可以进行互相调用的场景,即使其中有部分故障节点,但这样做可以继续保障大多数服务的正常消费。

Camden版本,整合了spring retry来增强RestTemplate的重试能力,对于我们开发者来说,只需要简单配置,即可完成重试策略。

spring.cloud.loadbalancer.retry.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

user-service.ribbon.ConnectTimeout=250
user-service.ribbon.ReadTimeout=1000
user-service.ribbon.OkToRetryOnAllOperations=true
user-service.ribbon.MaxAutoRetriesNextServer=2
user-service.ribbon.maxAutoRetries=1

spring.cloud.loadbalancer.retry.enabled:该参数用来开启重试机制,它默认是关闭的。

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:断路器的超时时间需要大于Ribbon的超时时间,不然不会触发重试。

user-service.ribbon.ConnectTimeout:请求连接超时时间。
user-service.ribbon.ReadTimeout:请求处理的超时时间
user-service.ribbon.OkToRetryOnAllOperations:对所有操作请求都进行重试。
user-service.ribbon.MaxAutoRetriesNextServer:切换实例的重试次数。
user-service.ribbon.maxAutoRetries:对当前实例的重试次数。

根据以上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由maxAutoRetries配置),如果不行,就换一个实例进行访问,如果还是不行,再换一个实例访问(更换次数由MaxAutoRetriesNextServer配置),如果依然不行,返回失败。



作者:二月_春风
链接:https://www.jianshu.com/p/f86af82fa782
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多