美文网首页
SpringCloud Ribbon负载均衡技术

SpringCloud Ribbon负载均衡技术

作者: pipiwen | 来源:发表于2019-02-25 21:26 被阅读0次

    我们在spring-cloud中要使用ribbon做负载均衡的时候一般会添加如下包:

    并在@Configuration的javaconfig配置中配置如下restTemplate,加上注解@LoadBalanced则实现了前端负载均衡。

    下面看看Ribbon的原理:

    核心为org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient类:

    LoadBalancerClient的实现类为RibbonLoadBalancerClient,这个类是非常重要的一个类,最终的负载均衡的请求处理,由它来执行。

    RibbonLoadBalancerClient的核心方法如下:

    可知,LoadBalancerClient的选择服务器实例的方法最终是由ILoadBalancer的chooseServer来实现。

    ILoadBalancer的实现类为com.netflix.loadbalancer.DynamicServerListLoadBalancer:

    其中其核心的属性为IRule和Iping

    IRule有很多默认的实现类,这些实现类根据不同的算法和逻辑来处理负载均衡。Ribbon实现的IRule有一下。在大多数情况下,这些默认的实现类是可以满足需求的,如果有特性的需求,可以自己实现。

    BestAvailableRule 选择最小请求数

    ClientConfigEnabledRoundRobinRule 轮询

    RandomRule 随机选择一个server

    RoundRobinRule 轮询选择server

    RetryRule 根据轮询的方式重试

    WeightedResponseTimeRule 根据响应时间去分配一个weight ,weight越低,被选择的可能性就越低

    ZoneAvoidanceRule 根据server的zone区域和可用性来轮询选择。

    IPing是用来想server发生”ping”,来判断该server是否有响应,从而判断该server是否可用。

    PingUrl 真实的去ping 某个url,判断其是否alive

    PingConstant 固定返回某服务是否可用,默认返回true,即可用

    NoOpPing 不去ping,直接返回true,即可用。

    DummyPing 直接返回true,并实现了initWithNiwsConfig方法。

    NIWSDiscoveryPing,根据DiscoveryEnabledServer的InstanceInfo的InstanceStatus去判断,如果为InstanceStatus.UP,则为可用,否则不可用。

    在DynamicServerListLoadBalancer的构造函数中会调用initWithNiwsConfig,配置相应的IRule和Iping的属性,并调用了restOfInit()方法:

    serverListImpl的实现类为com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList类,查看getUpdatedListOfServers()方法:

        其中eurekaClientProvider的实现类是LegacyEurekaClientProvider,它是一个获取eurekaClient类,通过加锁的实例方法去获取eurekaClient,其代码如下:

    urekaClient的实现类为DiscoveryClient,由此可见,负载均衡器是从EurekaClient获取服务信息,并根据IRule去路由,并且根据IPing去判断服务的可用性。

    负载均衡器多久会同步Eureka的注册列表数据呢?

    回到最初的DynamicServerListLoadBalancer构造器中,实例化的时候调用了BaseLoadBalancer的构造方法开启了一个PingTask任务,代码如下:

    setupPingTask()的具体代码逻辑,它开启了ShutdownEnabledTimer执行PingTask任务,在默认情况下pingIntervalSeconds为10,即每10秒钟,想EurekaClient发送一次”ping”。

    查看Pinger的runPinger()方法,最终根据 pingerStrategy.pingServers(ping, allServers)来获取服务的可用性,如果该返回结果,如之前相同,则不去向EurekaClient获取注册列表,如果不同则通知ServerStatusChangeListener或者changeListeners发生了改变,进行更新或者重新拉取。

    由此可见,LoadBalancerClient是在初始化的时候,会向EurekaClient拉取服务注册列表,并且向通过10s一次向EurekaClient发送“ping”,来判断服务的可用性,如果服务的可用性发生了改变或者服务数量和之前的不一致,则更新或者重新拉取。LoadBalancerClient有了这些服务注册列表,就可以根据具体的IRule来进行负载均衡。

    RestTempalate与Ribbon结合

    在该类中,首先维护了一个被@LoadBalanced修饰的RestTemplate对象的List,在初始化的过程中,通过调用customizer.customize(restTemplate)方法来给RestTemplate增加拦截器LoadBalancerInterceptor。

    而LoadBalancerInterceptor,用于实时拦截,在LoadBalancerInterceptor这里实现来负载均衡。LoadBalancerInterceptor的拦截方法如下:

    查看RibbonLoadBalancerClient的execute方法:

    最终由IRule的策略选取实例。

    综上所述,Ribbon的负载均衡,主要通过LoadBalancerClient来实现的,而LoadBalancerClient具体交给了ILoadBalancer来处理,ILoadBalancer通过配置IRule、IPing等信息,并向EurekaClient获取注册列表的信息,并默认10秒一次向EurekaClient发送“ping”,进而检查是否更新服务列表,最后,得到注册列表后,ILoadBalancer根据IRule的策略进行负载均衡。

    而RestTemplate 被@LoadBalanced注解后,能过用负载均衡,主要是维护了一个被@LoadBalance注解的RestTemplate列表,并给列表中的RestTemplate添加拦截器,进而交给负载均衡器去处理。

    参考:https://blog.csdn.net/forezp/article/details/74820899

    相关文章

      网友评论

          本文标题:SpringCloud Ribbon负载均衡技术

          本文链接:https://www.haomeiwen.com/subject/uchnyqtx.html