• Spring Boot + Spring Cloud 构建微服务系统(二):服务消费和负载(Ribbon)


    使用RestTemplate调用服务

    在上一篇教程中,我们是这样调用服务的,先通过 LoadBalancerClient 选取出对应的服务,然后使用 RestTemplate 进行远程调用。

    LoadBalancerClient 就是负载均衡器,默认使用的是 Ribbon 的实现 RibbonLoadBalancerClient,采用的负载均衡策略是轮询。

    package com.louis.spring.cloud.consul.consumer.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class RibbonHelloController {
    
        @Autowired
        private LoadBalancerClient loadBalancer;
    
        @RequestMapping("/call")
        public String call() {
            // 查找服务
            ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
            // 调用服务
            String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
            return callServiceResult;
        }
    }

    使用Ribbon实现负载均衡

    Ribbon介绍

    Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

    ribbon内置负载均衡策略:

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

    修改启动器

    修改 spring-cloud-consul-consumer 工程下的启动器类,注入 RestTemplate,并添加 @LoadBalanced 注解(用于拦截请求),以使用 ribbon 来进行负载均衡。

    package com.louis.spring.cloud.consul.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    public class ConsuleConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsuleConsumerApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

    添加服务

    新建 RibbonHelloController 类,注入 RestTemplate。

    package com.louis.spring.cloud.consul.consumer.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class RibbonHelloController {
    
        @Autowired
        private RestTemplate restTemplate;
        
        @RequestMapping("/ribbon/call")
        public String call() {
            // 调用服务, service-producer为注册的服务名称,LoadBalancerInterceptor会拦截调用并根据服务名找到对应的服务
            String callServiceResult = restTemplate.getForObject("http://service-producer/hello", String.class);
            return callServiceResult;
        }
    }

    测试效果

    启动消费者服务,访问 http://localhost:8521/ribbon/call,依次返回结果如下:

    helle consul
    helle consul two
    ...

    说明 ribbon 的负载均衡已经成功启动了。

    修改策略

    修改负载均衡策略很简单,只需要在配置文件指定对应的负载均衡器即可。如这里把策略修改为随机策略。

    application.yml

    #ribbon 负载均衡策略配置, service-producer为注册的服务名
    service-producer:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

    完成启动之后,发现 hello consul 和  hello consul two 结果不再交替出现,而是随机出现,说明策略修改成功了。

     

    源码下载

    码云:https://gitee.com/liuge1988/spring-cloud-demo.git


    作者:朝雨忆轻尘
    出处:https://www.cnblogs.com/xifengxiaoma/ 
    版权所有,欢迎转载,转载请注明原文作者及出处。

  • 相关阅读:
    [Operate System & Algorithm] 页面置换算法
    [Network] 计算机网络基础知识总结
    [Search Engine] 搜索引擎技术之网络爬虫
    [Search Engine] 搜索引擎分类和基础架构概述
    [Math] 常见的几种最优化方法
    磁盘告警之---神奇的魔法(Sparse file)
    Kubernetes概念之RC
    Kubernetes概念之mater、node
    Centos7允许使用密码登录
    安装gcc-c++报错解决办法
  • 原文地址:https://www.cnblogs.com/xifengxiaoma/p/9805475.html
Copyright © 2020-2023  润新知