当前位置:   article > 正文

【微服务笔记05】微服务组件之Ribbon负载均衡器组件介绍及其使用_微服务负载均衡组件

微服务负载均衡组件

这篇文章,主要介绍微服务组件之Ribbon负载均衡器及其使用。

目录

一、Ribbon负载均衡器

1.1、负载均衡介绍

(1)负载均衡概念

(2)负载均衡分类

(3)Ribbon负载均衡思想

1.2、Ribbon的使用

(1)引入Ribbon依赖

(2)开启Ribbon负载均衡

(3)编写测试类

(4)启动工程测试

1.3、常见的负载均衡策略

(1)如何使用负载均衡策略

(2)自定义负载均衡策略


一、Ribbon负载均衡器

1.1、负载均衡介绍

(1)负载均衡概念

上一篇文章介绍了OpenFeign组件,这个组件主要是用于实现微服务之间的调用,既然微服务之间可以调用了,那么问题又来了,假设在某个时间里面,微服务A的访问请求非常多,导致微服务A无法处理过来,从而导致微服务A宕机,对于这种情况,我们应该专门避免呢???

对于上面这种情况,我们可以这样解决,既然一台微服务A无法处理那么多的请求,那如果是多台微服务A应用程序呢,这样子是不是就可以将请求平均分配到不同的微服务A机器上面,从而减少某一台微服务A的请求处理量,避免服务宕机情况的出现,这里介绍的思想就是:负载均衡。

负载均衡:将HTTP请求按照某个策略,将请求分发到不同的机器上面执行,从而实现服务的高可用,这个过程大致就是负载均衡的思想,如下图所示。

(2)负载均衡分类

负载均衡如果按照软件、硬件来划分,则可以分为下面两种:

  • 硬件负载均衡器:采用硬件来实现负载均衡,常见的设备有:F5、交换机。
  • 软件负载均衡器:采用软件应用程序来实现负载均衡,常见的软件有:nginx。

根据负载均衡分发请求的不同位置,又可以将负载均衡器分为服务端负载均衡、客户端负载均衡,如下:

  • 服务端负载均衡:客户端发送的请求,到达服务端之前,通过采用软件负载均衡器将请求分发到不同的服务器上,这种方式称作:服务端负载均衡。
    • 服务端负载均衡,常见的是:nginx。
  • 客户端负载均衡:在客户端发送请求之前,就已经通过客户端内置的程序,指定当前这次请求应该转发到那一台服务器上,这种方式称作:客户端负载均衡。
    • 客户端负载均衡,常见的是:Ribbon。

这篇文章要介绍Ribbon就是典型的客户端负载均衡器,下面介绍Ribbon实现客户端负载均衡的大致思想。

(3)Ribbon负载均衡思想

在微服务的环境下,服务之间的调用都是通过Eureka注册中心(或者其他的注册中心)来获取到需要调用的服务地址,既然可以获取到服务地址,那是不是就可以在调用微服务之前,通过编写一个算法,选择当前HTTP请求应该选择哪一个服务地址进行调用呢???Ribbon就是实现了这一个算法,这个算法将他称作是:【负载均衡策略】,一个【负载均衡策略】其实就相当于是一种选择调用地址的算法。

  • 1、根据需要调用的微服务名称,找出这个微服务所有可用的地址。
  • 2、默认采用轮询的方式,依次遍历调用所有可用微服务地址。
  • 3、选择可用地址,利用RestTemplate实现服务的调用。

在Ribbon组件中,默认采用的是【轮询】的负载均衡策略,也就是说,将可用服务地址按照顺序一次循环调用,Ribbon中提供了很多中负载均衡策略,后面会具体介绍各种负载均衡策略。

Ribbon负载均衡大致思想如下图所示:

1.2、Ribbon的使用

(1)引入Ribbon依赖

  • Ribbon是Spring Cloud Netflix项目下的子工程,它的依赖是【spring-cloud-starter-netflix-ribbon】。
  • 因为Ribbon需要从eureka注册中心获取可用服务列表,所以还需要引入【spring-cloud-starter-netflix-eureka-client】依赖。
  1. <dependencies>
  2. <!-- 引入 Web 工程 -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <!-- 引入 eureka 服务端依赖 -->
  8. <dependency>
  9. <groupId>org.springframework.cloud</groupId>
  10. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  11. </dependency>
  12. <!-- 引入 Ribbon 依赖 -->
  13. <dependency>
  14. <groupId>org.springframework.cloud</groupId>
  15. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  16. </dependency>
  17. </dependencies>

(2)开启Ribbon负载均衡

  • Ribbon负载均衡会作用在所有采用【RestTemplate】方式进行调用的请求上,当我们在注入RestTemplate对象时候,使用了【@LoadBalanced】注解,那么这个时候,对于所有采用RestTemplate调用的请求,都将具有Ribbon负载均衡效果。
  1. package com.gitcode.ribbon.config;
  2. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.client.RestTemplate;
  6. /**
  7. * @version 1.0.0
  8. * @Date: 2023/1/11 21:16
  9. * @Copyright (C) ZhuYouBin
  10. * @Description:
  11. */
  12. @Configuration
  13. public class RibbonConfig {
  14. @Bean
  15. @LoadBalanced // 开启 Ribbon 实现负载均衡
  16. public RestTemplate restTemplate() {
  17. return new RestTemplate();
  18. }
  19. }

(3)编写测试类

  • 这里我们可以编写三个provider服务提供者,一个consumer服务消费者,然后在服务消费者中使用Ribbon测试负载均衡功能。

  • 服务消费者的调用逻辑如下所示。
  1. package com.gitcode.ribbon.controller;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import org.springframework.web.client.RestTemplate;
  7. import java.util.Map;
  8. /**
  9. * @version 1.0.0
  10. * @Date: 2023/1/11 21:19
  11. * @Copyright (C) ZhuYouBin
  12. * @Description:
  13. */
  14. @RestController
  15. @RequestMapping("/api/ribbon")
  16. public class DemoController {
  17. @Autowired
  18. private RestTemplate restTemplate;
  19. @GetMapping("/getUserInfo")
  20. public Map<String, String> getUserInfoByRestTemplate(String username) {
  21. // 获取微服务的虚拟地址
  22. String url = "http://service-provider/api/service/provider/getUserInfo";
  23. // 通过 RestTemplate 调用接口
  24. return restTemplate.postForObject(url, null, Map.class, username);
  25. }
  26. }

(4)启动工程测试

  • 依次启动【eureka注册中心】、三个【provider服务提供者】,一个【consumer服务消费者】服务。
  • 打开浏览器,访问【http://localhost:8761/】注册中心,查看服务是否正常注册成功。

以上日志说明,Ribbon负载均衡默认采用的【轮询】方式,也就是从第一台服务开始一次处理请求,到第三台服务处理结束了,又会回到第一台服务继续这个循环。

1.3、常见的负载均衡策略

Ribbon提供了多种负载均衡的策略,Ribbon将策略抽象为一个【IRule】接口,这个【IRule】接口的实现类就定义了各种负载均衡器的算法策略,常见的策略有如下这些:

  • 随机策略(Random):采用随机的方式选择服务调用地址。
  • 轮询策略(RoundRobin):按照从头到尾循环选择的方式调用服务地址,默认策略。
  • 加权轮询策略(WeightedResponseTime):一开始某一个服务地址都没有权重,所以默认采用轮询方式调用,当调用每一个服务地址时候,都会记录服务响应时间,Ribbon会根据响应时间给这个服务地址设置一个权重,下一次调用时候会根据权重来选择需要调用哪个地址,响应时间越短,说明这个服务机器性能越好,处理的效率越高,下一次被选中的概率就越大。
  • 重试轮询策略(Retry):默认采用轮询策略,如果选择的服务地址可以则直接调用,服务地址不可用,则循环重试选择可以服务地址。
  • 最小并发策略(BestAvailable):首先将所有不可用的服务去掉,然后从可用服务列表里面获取并发数量最小的地址进行调用,由于一开始还每月并发数量,所以默认先采用轮询策略,一段时间之后,改用最小并发策略。
  • 过滤不可用策略(AvailabilityFiltering):首先将不可用的服务、并发连接数超过阈值的服务全部过滤掉,然后采用轮询的策略选择调用地址。

(1)如何使用负载均衡策略

要使用Ribbon提供的其他负载均衡策略,我们只需要手动注入一个【IRule】对象即可。代码如下所示:

  1. /**
  2. * 使用Ribbon提供的其他负载均衡策略
  3. */
  4. @Bean
  5. public IRule ribbonRule() {
  6. return new RandomRule(); // 这里采用随机策略
  7. }

上面代码会对所有的微服务都采用【随机策略】,如果你想根据不同的微服务来选择不同的负载均衡策略,那么可以在【application.yml】配置文件中单独设置某个微服务的负载均衡策略。

  • 注意:通过【@Bean】注入的方式定义负载均衡策略的优先级更高,所以不要和配置文件的方式一起使用,否则配置文件的策略不生效。
  1. # ribbon 配置
  2. RIBBON-PROVIDER: # 这里就是单独给 RIBBON-PROVIDER 微服务设置 Ribbon 相关配置属性
  3. ribbon:
  4. # 指定 Ribbon 的负载均衡策略
  5. NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule # 这里采用轮询策略

(2)自定义负载均衡策略

如果Ribbon提供的那几种负载均衡策略都不满足你的需求,那么我们可以自定义负载均衡策略,只需要实现【IRule】接口,重写其中的方法完成负载均衡算法即可。

但是如果直接实现【IRule】接口,那就需要重写接口中的所有方法,这样太麻烦了,所以Ribbon给我们提供了一个抽象类【AbstractLoadBalancerRule 】,我们继承这个类,只需要重写【initWithNiwsConfig()】方法和【choose()】方法即可完成自定义负载均衡策略。

  • 自定义CustomRibbonRule负载均衡策略类。
  1. package com.gitcode.ribbon.config;
  2. import com.netflix.client.config.IClientConfig;
  3. import com.netflix.loadbalancer.AbstractLoadBalancerRule;
  4. import com.netflix.loadbalancer.ILoadBalancer;
  5. import com.netflix.loadbalancer.Server;
  6. import java.util.List;
  7. import java.util.Random;
  8. /**
  9. * @version 1.0.0
  10. * @Date: 2023/1/11 22:36
  11. * @Copyright (C) ZhuYouBin
  12. * @Description:
  13. */
  14. public class CustomRibbonRule extends AbstractLoadBalancerRule {
  15. @Override
  16. public void initWithNiwsConfig(IClientConfig iClientConfig) {
  17. }
  18. @Override
  19. public Server choose(Object o) {
  20. // 从父类中获取负载均衡器对象
  21. ILoadBalancer lb = getLoadBalancer();
  22. // 获取所有可以服务
  23. List<Server> reachableServers = lb.getReachableServers();
  24. // 随机选择一个服务地址
  25. Random random = new Random();
  26. int index = random.nextInt(reachableServers.size() - 1);
  27. // 返回这个选择服务地址
  28. return reachableServers.get(index);
  29. }
  30. }
  • 注册自定义的负载均衡策略。
  1. /**
  2. * 使用自定义的负载均衡策略
  3. */
  4. @Bean
  5. public IRule ribbonRule() {
  6. return new CustomRibbonRule(); // 自定义负载均衡策略
  7. }

到此,微服务组件Ribbon介绍完啦。

综上,这篇文章结束了,主要介绍微服务组件之Ribbon负载均衡器及其使用【源代码】。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号