zoukankan      html  css  js  c++  java
  • Spring Cloud之Ribbon负载均衡(Spring Cloud 2020.0.3版)

    Spring Cloud Ribbon

    demo代码放在github上 ,需要的请点这里--> demo

    1. Ribbon简介

    一般来说,在生产环境中,各个微服务都会部署多个实例。那么消费者要如何将请求分摊到多个服务提供者实例上呢?负载均衡在系统架构中一个非常重要,不得不去实施的内容,负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。通常所说的负载均衡都是指服务端负载均衡,其中分为硬件负载均衡(如F5)和软件负载均衡(如Nginx)。Ribbon是NetFlix发布的客户端负载均衡器,它有助于控制Http和Tcp客户端的行为。通过SpringCloud的封装,可以让我们轻松的将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个SpringCloud构建的微服务和基础设施中。

    客户端负载均衡和服务端负载均衡的区别?

    TODO: 最大的区别就是服务清单存储的位置,

    • 服务端负载均衡

    image-20210517151757123

    2. Ribbon的使用

    1. 通过Spring Cloud Ribbon的封装,在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:

      • 服务提供者只需要启动多个服务实例并注册到服务注册中心

      • 服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用

    2. 具体布步骤如下:

      1. 在服务消费者微服务的POM文件中添加ribbon的依赖

        <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
              <version>2.2.8.RELEASE</version>
        </dependency>

        在spring cloud Eureka依赖中已经包含了spring cloud ribbon,因此无需再次引入。如过已经添加了的spring cloud Eureka依赖,不要添加该依赖,否则会遇到空指针错误。

      2. 服务提供者微服务中给RestTemplate添加@LoadBalanced注解

        @Bean
            @LoadBalanced
            public RestTemplate restTemplate()
            {
                return new RestTemplate();
            }

        image-20210517160434607

      3. 对服务消费者的controller代码进行修改

         @Autowired
            private RestTemplate restTemplate;
        ​
            @Autowired
            private LoadBalancerClient loadBalancerClient;
        ​
            @GetMapping("/user/{id}")
            public User findById(@PathVariable long id)
            {
                //hardCode硬编码方式不可取
               //return restTemplate.getForObject("http://localhost:8000/" + id,User.class);
        //修改成通过微服务的虚拟主机名来访问
                return restTemplate.getForObject("http://userservice/"+id,User.class);
            }
        ​
            @GetMapping("/log-user-instance")
            public void logUserInstances()
            {
                ServiceInstance serviceInstance = loadBalancerClient.choose("userservice");
                log.info("serviceId-->{},Host-->{},port-->{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
            }

        新增加了一个API接口,服务消费者访问该接口时打印出IP地址和端口号

        image-20210517160749653

      4. 现在分别启动1个服务注册中和2个服务提供者、1个服务消费者

        • 服务注册中心

          image-20210517161222111

           

        • 服务提供者

          image-20210517161324308

          这里提供一下如何在idea中如何启动两个不同端口号的服务提供者的实例

          • 在服务提供者的配置文件中已经配置了server.port=8000,因此第一个实例直接点击运行就可以咯

            image-20210517162309499

          • 选择Idea右上角启动按钮边上的Edit Configurations,在打开的对话框中,选择UserServiceApplication-->点击复制按钮->VM Options中增加-Dserver.port=8001,Apply应用,如图:

            image-20210517162438058

            最后点击运行就可以运行port=8001的实例咯

        • 服务消费者

          启动服务消费者,然后不断的访问API接口地址http://localhost:8081/log-user-instance,发现交替打印服务消费者的ip地址。

          image-20210517163043521

    搭建过程中遇到的问题:

    添加该依赖后,运行时报空指针错误,去掉该依赖后能正常访问。image-20210517175714002

    报错信息如下:

    image-20210517175601096

    出现该问题的根本原因是Spring Cloud 2020.0.0版本以后对Spring Cloud NetFlix 组件进行剔除,仅保留了Eureka组件,其核心组件 Hystrix、Ribbon、Zuul、Archaius 等均进入维护状态


    旧版本的spring-cloud-netflix-dependencies管理着Netflix所有组件,包括Hystrix、Ribbon、Zuul、Eureka等。而自2020.0版本起,它有且只管理Eureka(包括Server和Client)
    其中Feign虽然最初属Netflix公司,但从9.x版本开始就移交给OpenFeign组织管理了,因此不再划入Netflix管辖范畴。

    简单一句话概括:Spring Cloud 2020.0.0版本彻底删除掉了Netflix除Eureka外的所有组件

    image-20210518111000347

    Spring Cloud 既然把 Netflix 套件大刀阔斧的砍掉了,那总归得有替代方案吧。那是必然的,Spring Cloud 团队给我们推荐了用于替代的组件:

    image-20210518110911185

    image-20210518112004676

    Spring Cloud LoadBalancer 目前仅支持轮询负载均衡策略,相对于 Ribbon 多种高可用策略还是过于简单。

    3. Ribbon负载均衡策略

    很多场景下,可能根据需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则等。

    方法一和二适合于Spring Cloud 2020.0.0版本之前的版本,方法三适合Spring Cloud 2020.0.0版之后的Spring Cloud版本

    方法一:配置文件的方式

    在application.propertites文件中添加如下代码:

    #更改负载均衡的负载策略
    userservice.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

    image-20210517223443589

    方法二:使用Java代码自定义Ribbon配置

    使用Ribbon提供的负载均衡策略很简单

    • 创建具有负载均衡功能的RestTemplate实例

      @Bean
      @LoadBalanced
      RestTemplate restTemplate() {
          return new RestTemplate();
      }

      使用RestTemplate进行rest操作的时候,会自动使用负载均衡策略,它内部会在RestTemplate中加入LoadBalancerInterceptor这个拦截器,这个拦截器的作用就是使用负载均衡。

    • 默认情况下会采用轮询策略,如果希望采用其它策略,则指定IRule实现,如:

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

    方法三:负载均衡策略配置(适用于Spring Cloud 2020.0.0版之后的版本

    spring cloud加入了一个新模块Spring-Loadbalancer来替代ribbon,有两种负载均衡模式(轮询和随机),默认是用轮询,假如想使用随机或者自定义负载均衡策略,就不能按照以前使用ribbon的模式(注入IRule类,必须引入ribbon依赖),那么如果我使用Loadbalancer的随机负载均衡,要怎么设置呢?官网给出比较详细的方法

    显然官方写了一个切换成随机负载均衡的例子,我们拷贝过来即可。

    image-20210518112950963

    @Bean
            ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                                    LoadBalancerClientFactory loadBalancerClientFactory) {
                String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
                return new RandomLoadBalancer(loadBalancerClientFactory
                        .getLazyProvider(name, ServiceInstanceListSupplier.class),
                        name);
    ​
    • 搭建步骤

      1. 把官方的@Bean方法拷贝到自己的配置类(这个类可以放到主启动类所在包及子包下,这一点和Ribbon不同

        image-20210518114000731

      2. 在启动类,使用@LoadBalancerClient或者@LoadBalancerClients注解,加载自己的配置类,由此切换loadBalancer默认的负载均衡策略

        image-20210518114034152

      3. 然后运行代码发现就切换成随机负载均衡策略咯

    image-20210518113209128

    4. Ribbon自定义负载均衡策略

    可以参考这篇博客: https://blog.csdn.net/qq_35799668/article/details/114534023

     

     

     

  • 相关阅读:
    权值线段树&&可持久化线段树&&主席树
    扩展中国剩余定理(EXCRT)快速入门
    jquery学习记录
    隐藏vbs执行cmd命令的窗口
    eclipse打开出错 Error: opening registry key 'SoftwareJavaSoftJava Runtime Environment'
    正则表达式学习总结
    什么是xss攻击?
    什么是浏览器的同源策略?
    关于axios的封装
    关于递归。
  • 原文地址:https://www.cnblogs.com/seanRay/p/14781110.html
Copyright © 2011-2022 走看看