vlambda博客
学习文章列表

负载均衡:Ribbon 如何保证微服务的高可用

负载均衡:Ribbon 如何保证微服务的高可用

如何实现有效的服务间稳定通信是本文即将介绍的主要内容,主要学习三方面知识:

  1. 介绍 Ribbon 负载均衡器;

  2. 讲解 Ribbon+RestTemplate 两种实现方式;

  3. 讲解 Ribbon 的负载均衡策略。

Ribbon 负载均衡器

负载均衡顾名思义,是指通过软件或者硬件措施。它将来自客户端的请求按照某种策略平均的分配到集群的每一个节点上,保证这些节点的 CPU、内存等设备负载情况大致在一条水平线,避免由于局部节点负载过高产生宕机,再将这些处理压力传递到其他节点上产生系统性崩溃。

负载均衡按实现方式分类可区分为:服务端负载均衡与客户端负载均衡。

服务端负载均衡顾名思义,在架构中会提供专用的负载均衡器,由负载均衡器持有后端节点的信息,服务消费者发来的请求经由专用的负载均衡器分发给服务提供者,进而实现负载均衡的作用。目前常用的负载均衡器软硬件有:F5、Nginx、HaProxy 等。

负载均衡:Ribbon 如何保证微服务的高可用

客户端负载均衡是指,在架构中不再部署额外的负载均衡器,在每个服务消费者内部持有客户端负载均衡器,由内置的负载均衡策略决定向哪个服务提供者发起请求。说到这,我们的主角登场了,Netfilx Ribbon 是 Netflix 公司开源的一个负载均衡组件,是属于客户端负载均衡器。目前Ribbon 已被 Spring Cloud 官方技术生态整合,运行时以 SDK 形式内嵌到每一个微服务实例中,为微服务间通信提供负载均衡与高可用支持。为了更容易理解,我们通过应用场景说明 Ribbon 的执行流程。假设订单服务在查询订单时需要附带对应商品详情,这就意味着订单服务依赖于商品服务,两者必然产生服务间通信,此时 Ribbon 的执行过程如下图所示

  1. 订单服务(order-service)与商品服务(goods-service)实例在启动时向 Nacos 注册;

  2. 订单服务向商品服务发起通信前,Ribbon 向 Nacos 查询商品服务的可用实例列表;

  3. Ribbon 根据设置的负载策略从商品服务可用实例列表中选择实例;

  4. 订单服务实例向商品服务实例发起请求,完成 RESTful 通信;

Ribbon+RestTemplate 实现服务间高可用通信

ribbon是再消费者端。

RestTemplate 对象是Spring Cloud 封装的 RESTful 通信对象,它封装了基于 HTTP 协议的操作,通过简单的API便可发起 HTTP 请求并自动处理响应。RestTemplate 天然与 Ribbon 兼容,两者配合可以极大简化服务间通信过程。Ribbon + RestTemplate 提供了两种开发模式:代码模式,注解模式。

这里就不作代码演示。

代码式:使用RestTemplate进行服务间的通信,就是发送http请求。

注解模式:主要是利用 @LoadBalanced 注解可自动化实现这一过程。

Ribbon 的执行过程,先从 Nacos 获取可用服务提供者实例信息,再通过 RestTemplate.getForObject() 向该实例发起 RESTful 请求完成处理。

无论注解模式还是代码模式,默认的负载均衡策略都是轮询,即按顺序依次访问,作为 Ribbon 还支持哪些其他负载均衡策略呢?我们又该如何设置呢?

分为以下几种:

  1. RoundRobinRule:

    轮询策略,Ribbon 默认策略。默认超过 10 次获取到的 server 都不可用,会返回⼀个空的 server。

  2. RandomRule:

    随机策略,如果随机到的 server 为 null 或者不可用的话。会不停地循环选取。

  3. RetryRule:

    重试策略,⼀定时限内循环重试。默认继承 RoundRobinRule,也⽀持自定义注⼊,RetryRule 会在每次选取之后,对选举的 server 进⾏判断,是否为 null,是否 alive,并且在 500ms 内会不停地选取判断。而 RoundRobinRule 失效的策略是超过 10 次,RandomRule 没有失效时间的概念,只要 serverList 没都挂。

  4. BestAvailableRule:

    最小连接数策略,遍历 serverList,选取出可⽤的且连接数最小的⼀个 server。那么会调用 RoundRobinRule 重新选取。

  5. AvailabilityFilteringRule:

    可用过滤策略。扩展了轮询策略,会先通过默认的轮询选取⼀个 server,再去判断该 server 是否超时可用、当前连接数是否超限,都成功再返回。

  6. ZoneAvoidanceRule:

    区域权衡策略。扩展了轮询策略,除了过滤超时和链接数过多的 server,还会过滤掉不符合要求的 zone 区域⾥⾯的所有节点,始终保证在⼀个区域/机房内的服务实例进行轮询。

这里所有负载均衡策略名本质都是 com.netflix.loadbalancer 包下的类:


要更改微服务通信时采用的负载均衡策略也很简单,在 application.yml 中采用下面格式书写即可。

provider-service: #服务提供者的微服务id
ribbon:
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置对应的负载均衡类