最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇

Posted DT辰白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇相关的知识,希望对你有一定的参考价值。


前言

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。

一、Ribbon核心概念

Raibbon是基于Netflix Ribbon实现的一套客户端负载均衡工具。Raibbon客户端提供了一系列的配置,如超时、重试、负载均衡等,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要,比如微服务之间的调用,API网关的转发请求等,实际上都是通过Ribbon来完成的。

通俗的来说:Ribbon = 负载均衡 + RestTemplate

这里提到了一个词,叫做客户端负载均衡,那么可能会想到我们的nginx,那么Nginx是客户端负载均衡吗?不是,Nginx实际上是一种集中式负载均衡(服务器端负载均衡),并不属于客户端负载均衡范畴。那么这两者的区别是什么呢?

二、服务器端负载均衡和Riboon客户端负载均衡

1、服务器端负载均衡:

服务端负载均衡又分为两种,一种是硬件负载均衡,还有一种是软件负载均衡。

例如Nginx,是软件负载均衡,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配,我们来看一张图,使用Nginx做的负载均衡策略。

2、Riboon客户端负载均衡:

例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配。来直接上图,下图所示是我们本篇文章要实现的Ribbon负载均衡策略。

三、Ribbon策略

当我们在 RestTemplate 上添加 @LoadBalanced 注解后,就可以用服务名称来调用接口了,当有多个服务的时候,还能做负载均衡。然而Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等,并且我们还能够使用Ribbon实现自定义的负载均衡策略。

负载均衡常用策略方式:

  • 默认为轮训的策略方式
  • 随机
  • 重试(如果获取服务失败,在指定时间内进行重试,获取可用服务)
  • 过滤掉出故障的服务,选择一个最小并发量的服务


如下图为负载均衡轮训算法的实现:

四、Ribbon配置使用

这里我们使用Nacos作为注册中心,模拟订单服务于库存服务之间的调用,使用Ribbon作为客户端的负载均衡实现,他的配置方式很简单,下面我们就搭建好以下三个服务,准备实操一波。

服务名称端口号
dt-stock-service8083
dt-stock-service8082
dt-order-service8081

这里我们的库存服务为两个,订单服务为一个,通过订单服务调用库存服务,实现Ribbon的负载均衡,首先是订单服务启动类,我们把RestTemplate 注册进来,这里我们使用RestTemplate 来实现服务之间的调用,RestTemplate 只需要加上 @LoadBalanced 注解后,就可以用服务名称来调用接口了,既能实现Ribbon的负载均衡策略。

@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}

订单服务控制器调用接口如下:

@RestController
@RequestMapping(value = "order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("test")
    public String getOrder() {
        String msg = restTemplate.getForObject("http://dt-stock-service/stock/test", String.class);
        return "调用订单服务->>>"+msg;
    }
}

我们通过服务名称的方式(dt-stock-service)来调用库存服务接口方法,然后我们再编写库存服务控制器接口方法:

@RestController
@RequestMapping(value = "/stock")
public class StockController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/test")
    public String getStock() {
        return "调用库存服务:"+port;
    }
}

这里我们打印一下当前库存服务被调用的端口,以便观察Ribbon的负载均衡策略模式,服务架构如下。


我们启动8081订单服务,再依次启动8082、8083库存服务,服务启动之后,观察我们的注册中心服务实例变化,此时订单服务有一个实例,库存服务有两个实例,服务启动成功了,下面我们来发送接口测试:

发送请求:http://localhost:8081/order/test

第一次8083端口:

第二次8082端口:

一直发送接口请求测试,可以发现,都是8083和8082之间轮训切换调用,那就明白了,Ribbon默认的策略模式是轮询的方式,在文章开头我们说过Riboon的策略方式不止轮询,轮询只是它自身内部一种默认的实现方式,下面我们就来研究其他的几种常见的方式怎么玩?

五、配置自定义的负载均衡算法

1、按照权重实现负载均衡

Ribbon本身是没有权重的概念的, 那么如何才能实现代用权重的负载均衡呢? 我们在nacos中, 服务器的集群有一个权重的概念, 当给服务器设置了权重, 那么流量就可以根据权重比例分配到服务器上。

1.1 配置Ribbon

spring:
  application:
    name: dt-order-service
  cloud:
    nacos:
      server-addr: 47.108.191.196:9091
      discovery:
        username: nacos
        password: nacos
        namespace: public
ribbon:
  NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #指定全局的负载均衡算法
  eager-load:
    enabled: true             #开启饥饿模式
    clients: dt-stock-service #为哪些服务的名称开启饥饿加载,多个用逗号分隔

com.dt.springcloud.ribbon.config.GlobalRibbonConfig #指定全局的负载均衡算法类名

这里小编解释一下Ribbon为什么会有饥饿模式的配置:ribbon客户端不是在服务启动的时候加载的,所以可能第一次调用会很慢,甚至超时。

1.2 全局的负载均衡算法类

/**
 * 全局设置自定义的权重负载均衡策略
 * @author DT
 * @date 2021/8/7 20:39
 */
@Configuration
public class GlobalRibbonConfig {

    @Bean
    public IRule getRule() {
        // 实现带有权重的负载均衡策略
        return new MyWeightRule();
    }

}

1.3 自定义权重实现负载均衡

/**
 * 自定义一个权重负载均衡策略
 * @author DT
 * @date 2021/8/7 20:32
 */
public class MyWeightRule extends AbstractLoadBalancerRule {

    @Autowired
    private NacosDiscoveryProperties discoveryProperties;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) { }

    /**
     * 自定义实现负载均衡策略的方法
     */
    @Override
    public Server choose(Object key) {
        try {
            // 调用父类方法, 获取当前使用的负载均衡器
            BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
            // 获取当前服务的名称
            String serviceName = baseLoadBalancer.getName();
            // 获取nacos的服务发现API
            NamingService namingService = discoveryProperties.namingServiceInstance();
            //  nacos实现了权重的负载均衡算法
            Instance instance = namingService.selectOneHealthyInstance(serviceName);
            // 打印输出
            String threadName = Thread.currentThread().getName();
            System.out.println("线程->>>" + threadName + "->>>发送请求");
            System.out.println("IP端口->>>"+instance.getIp()+":"+instance.getPort());
            return new NacosServer(instance);
        } catch (NacosException e) {
            e.printStackTrace();
        }
        return null;
    }
}

1.4 设置Nacos服务实例权重比例



我们一个设置为0.3, 另一个设置成0.7, 也就是说如果有10次请求, 基本上都是会打到8082端口上的,因为8082的权重最高,打到它的接口数量应该是最多的。

1.4 测试负载均衡

http://localhost:8081/order/test


触发10次请求,基本7次左右都会打到8082服务上面。

六、Ribbon常用配置

ribbon:
  ConnectTimeout: 1000            #服务请求连接超时时间(毫秒)
  ReadTimeout: 3000               #服务请求处理超时时间(毫秒)
  OkToRetryOnAllOperations: true  #对超时请求启用重试机制
  MaxAutoRetriesNextServer: 1     #切换重试实例的最大个数
  MaxAutoRetries: 1               #切换实例后重试最大次数
  NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #修改负载均衡算法

在我们文章当中,使用的是全局配置,当然你也可以指定针对单独的服务配置:

#服务名
dt-order-service:
  ribbon:
     ConnectTimeout: 1000            #服务请求连接超时时间(毫秒)
	 ReadTimeout: 3000               #服务请求处理超时时间(毫秒)
	 OkToRetryOnAllOperations: true  #对超时请求启用重试机制
	 MaxAutoRetriesNextServer: 1     #切换重试实例的最大个数
	 MaxAutoRetries: 1               #切换实例后重试最大次数
	 NFLoadBalancerRuleClassName: com.dt.springcloud.ribbon.config.GlobalRibbonConfig #修改负载均衡算法

总结

好了,以上内容就是今天的输出,后面我们再继续深入研究微服务其他的组件的使用以及原理剖析,创作不易,喜欢的请关注小编CSDN:https://blog.csdn.net/qq_41107231 以及掘金:https://juejin.cn/user/3940246036699848

以上是关于最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud - Spring Cloud Alibaba

Spring Cloud Alibaba从入门到进阶

Spring Cloud Alibaba从入门到精通!

Spring Cloud Alibaba 实战 之 Nacos 服务注册和发现

Spring Cloud Alibaba 最新版发布!

Spring Cloud Alibaba 最新版发布!