您的位置:首页 > 编程语言 > Java开发

spring cloud ribbon - 负载均衡

2017-08-30 20:53 776 查看


相关文章:

Spring cloud - 概述

Spring cloud eureka - 注册中心

Spring cloud feign - RPC

Spring cloud ribbon - 负载均衡

Spring cloud hystrix - 断路器

Spring cloud hystrix dashboard - 断路器dashboard

Spring cloud zuul- 网关


1.关键字

   负载均衡

2.基本介绍
   上一次讲到远程调用的客户端feign,feign的主要功能就是远程对象的本地代理或者用于远程调用的httpClient,减化远程调用的复杂性,让本地调用远程方法如同调用本地方法一样简单方便。但是在集群环境,远程服务可能有多个可用节点,那么调用时就需要负载均衡。ribbon是一个提供客户端负载均衡算法的策略库。

  
   负载均衡主要有种方式,一种是服务端负载算法,一种是客户端负载算法。服务端算法主要是通过反向代理的方式把客户端请求分发到可用的节点,如:nginx。客户端算法则是先获取所有可用节点,再自己选择一个合适的节点。ribbon提供的负载均衡算法属于客户端算法。

3.什么是ribbon?
ribbon是一个建立在http或tcp之上的本地负载均衡器。feign使用ribbon进行负载,因此只要使用@FeignClient,就自动引用了ribbon.

ribbon最核心的概念是:一个被命名的client,也即一个具有唯一名字的客户端每一个负载均衡都是整体组件的一部分,它们相互协作调用远程服务。每一个client都会通过类RibbonClientConfiguration创建一个新的子spring
ApplicationContext,这个子ApplicationContext上下文的名子就是client的名字(如:@FeignClient("user-server"),每个ribbon客户端包含:ILoadBalancer,
 RestClient,  ServerListFilter, ServerList,IRule。
ILoadBalancer:是负载均衡的入口类。
ServerList:存储远程服务所有可用节点
ServerListFilter:用于过滤非法的远程节点(如:不可用等)
IRule:负载算法(策略),用于从可用节点选择一个合适的节点。
RestClient:远程调用

4.集成ribbon
  如果使用feign,则默认已经集成,否则手动集成;使用maven的pom.xml文件,配置如下:spring-cloud-starter-ribbon

   
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>


5.编码方式配置ribbon客户端
可以通过 <clientName>.ribbon.*   来自定义配置ribbon客户端。这此属性具体可参考类:CommonClientConfigKey,此类中包含了所有可能配置的属性key.

spring cloud允许使用自定义的配置文件对ribbon进行完全控制,如:@RibbonClient(name = "foo", configuration = FooConfiguration.class)通过注解中的configuration可以自定义的配置。这种情况下:RibbonClientConfiguration类中的配置和FooConfiguration类中的配置一起影响ribbonClient,基中FooConfiguration中的配置会覆盖RibbonClientConfiguration中的配置。
注意:FooConfiguration必须使用@Configuration进行注解,但是不能被scan到,否则变成全局对旬会被所有client使用。它必须放在scan外的包中,或者是使用scan中的exclude排队掉。这些配置都会在子ApplicationContext中被创建。

ribbon默认使用以下bean:

IClientConfig ribbonClientConfig: DefaultClientConfigImpl:配置
IRule ribbonRule: ZoneAvoidanceRule:负载算法(如何从可用中选一个)
IPing ribbonPing: NoOpPing:ping 检查远程服务是否存活
ServerList<Server> ribbonServerList: ConfigurationBasedServerList :远程服务节点列表
ServerListFilter<Server> ribbonServerListFilter: ZonePreferenceServerListFilter:过滤不符合要求的远程节点(如何排除不可用的节点)
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer:负载
ServerListUpdater ribbonServerListUpdater: PollingServerListUpdater:更新远程服务节点(同步远程节点信息)

示例:创建一个自定义的ping,会覆盖默认的ping bean.
@Configuration
public class FooConfiguration {
    @Bean
    public IPing ribbonPing(IClientConfig config) {
        return new PingUrl();
    }
}

6.配置文件配置ribbon客户端
从1.2.0版本,Spring Cloud Netflix支持使用properties配置文件配置Ribbon客户端。允许在启动时根据不同环境改变行为。
下面是相关配置,前提是必须加上前前缀:<clientName>.ribbon. 以下可以类可以通过配置文中指定自定义类,从而替换默认实现。

NFLoadBalancerClassName: should implement ILoadBalancer:负载均衡器全限定名
NFLoadBalancerRuleClassName: should implement IRule:负载策略(算法)全限定名
NFLoadBalancerPingClassName: should implement IPing:ping全限定名
NIWSServerListClassName: should implement ServerList:远程服务列表全限定名
NIWSServerListFilterClassName should implement ServerListFilter:过滤远程服务点节的过滤器全限定名

注意:配置文件中的配置优先级比@RibbonClient(configuration=MyRibbonConfig.class)中configuration指定的代码配置高,同时也比netflix默认的配置高

优化级如下:
配置文件 >  @RibbonClient(configuration=MyRibbonConfig.class)的MyRibbonConfig > 默认配置

示例:
下是为一个叫做“users”的微服务配置IRule,
application.yml
users:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule


7.集成eureka
  当使用eureka和ribbon时,ribbonServerList会被eureka中的DiscoveryEnabledNIWSServerList替换,通过eureka获取远程服务节点列表。

IPing会被NIWSDiscoveryPing替换,用于检查远程服务是否可用。ServerList 会被DomainExtractingServerList 替换。ribbon相关的组件会被替换成eureka对应的组件。

  如何替换?

  ribbon组件通过RibbonAutoConfiguration自动集成,而eureka 和ribbon则是通过RibbonEurekaAutoConfiguration自动集成。RibbonAutoConfiguration优先加载并创建,但并未创建对应的RibbonClientConfiguration(包含所有ribbon组件的创建)。RibbonEurekaAutoConfiguration在RibbonAutoConfiguration创建后加载并生成相应bean《通过@AutoConfigureAfter(RibbonAutoConfiguration.class)》。RibbonEurekaAutoConfiguration通过注解@RibbonClients(defaultConfiguration
= EurekaRibbonClientConfiguration.class)加载 EurekaRibbonClientConfiguration(包含所有eureka用于替换ribbon组件的bean)。由于EurekaRibbonClientConfiguration比aRibbonClientConfiguration优先创建,这个配置中的eureka
ribbon组件就优生成,通过注解 @ConditionalOnMissingBean,就可以阻止原生ribbon核心组件的生成,从而无缝替换。

8.关闭eureka功能
eureka是一个非常方便的,用于抽像 “发现远程服务节点”的方法,因此可以不用在本地硬编码远程服务节点的url地址。但是如果你不想使用eureka,但是 仍然使用Ribbon and Feign ,那么你可以通过@RibbonClient指定远程服务名,然后通过配置文件配置远程节点的url地址,此时需要关闭eureka(classpath下没有eureka包或者ribbon.eureka.enabled:
false主动关闭)

示例:假如有一个名叫"stores"的远程微服务,则以下为本地配置对应的远程节点url,多个以逗号分隔
application.yml
stores:
ribbon:
listOfServers: example.com,google.com

关闭eureka:
    application.yml
ribbon:
eureka:
enabled: false

直接使用ribbon api接口:
public class MyClass {
@Autowired
private LoadBalancerClient loadBalancer;

public void doStuff() {
ServiceInstance instance = loadBalancer.choose("stores");
URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
// ... do something with the URI
}
}


9.缓存Ribbon配置
每个命名的ribbon client(如:@FeignClient(value = "stores"))都会被创建一个子Application Context。即:一个远程微服服务对应的所api接口都会在本创建对应的代理bean,这些bean都存在于一个新的子Application Context。这些Application
Context由spring cloud维护。这些Application Context默认是在第一个请求时创建。不过Application Context的创建时机可以通过配置来改变,从而在项目启动时创建。

指定的远程服务对应的代理bean在服务启动时生成。
application.yml
ribbon:
eager-load:
enabled: true
clients: client1, client2, client3



10.Ribbon提供的主要负载均衡策略介绍

   1:简单轮询负载均衡(RoundRobin)

     以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。

   2:随机负载均衡 (Random)

     随机选择状态为UP的Server

   3:加权响应时间负载均衡 (WeightedResponseTime)

     根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。

   4:区域感知轮询负载均衡(ZoneAvoidanceRule)

     复合判断server所在区域的性能和server的可用性选择server

  Ribbon自带负载均衡策略比较
策略 名     策略声明策略描述实现说明
Best AvailableRulepublic class BestAvailableRule extends ClientConfigEnabledRoundRobinRule选择一个最小的并发请求的server逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRulepublic class AvailabilityFilteringRule extends PredicateBasedRule过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRulepublic class WeightedResponseTimeRule extends RoundRobinRule根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。一 个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择 server。
RetryRulepublic class RetryRule extends AbstractLoadBalancerRule对选定的负载均衡策略机上重试机制。在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRulepublic class RoundRobinRule extends AbstractLoadBalancerRuleroundRobin方式轮询选择server轮询index,选择index对应位置的server
RandomRulepublic class RandomRule extends AbstractLoadBalancerRule随机选择一个server在index上随机,选择index对应位置的server
ZoneAvoidanceRulepublic class ZoneAvoidanceRule extends PredicateBasedRule复合判断server所在区域的性能和server的可用性选择server使 用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个 zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的 Server。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: