源生Ribbon介绍 --- 客户端负载均衡器 - 01

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源生Ribbon介绍 --- 客户端负载均衡器 - 01相关的知识,希望对你有一定的参考价值。

源生Ribbon介绍 --- 客户端负载均衡器 - 01


前言

Netflix RibbonNetflix OSS的一部分,它是一个基于HTTP和TCP客户端负载均衡器。它虽然只是一个工具类库,并不需要像eureka注册中心、网关服务那样单独部署,但它却是每一个微服务的基础设施。因为实际上,对于服务间调用、API网关请求转发都需要经过Ribbon负载均衡来实现,比如我们熟悉的Feign发送请求也得经过它(当然这不是必须,只是已经成为了事实标准)。

负载均衡是互联网开发避不开的核心概念之一,它是HA高可用的最有效手段。而在微服务日益流行的今天,对Ribbon的理解和使用,对于我们构建微服务非常重要。


正文

官网:https://github.com/Netflix/ribbon Ribbon中文释义:带;缎带;把…撕成条带

Ribbon是一个内置软件负载平衡器的进程间通信(远程过程调用)库。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。

说明:ribbon“后面的机器”可以来自于写死、配置或者是任意注册中心,当然使用得最多的是和自己兄弟eureka的无缝整合最为平滑


什么是负载均衡器?

假设有一个分布式系统,该系统由在不同计算机上运行的许多服务组成。但是,当用户数量很大时,通常会为服务创建多个副本。每个副本都在另一台计算机上运行。此时,出现 Load Balancer(负载均衡器)。它有助于在服务器之间平均分配传入流量。


服务端负载均衡器

传统上,Load Balancers(例如nginx、F5)是放置在服务器端的组件。当请求来自 客户端 时,它们将转到负载均衡器,负载均衡器将为请求指定 服务器。负载均衡器使用的最简单的算法是随机指定。在这种情况下,大多数负载平衡器是用于控制负载平衡的硬件集成软件。

  • 服务端地址对客户端透明,客户端不知道服务器端的服务列表,甚至不知道自己发送请求的目标地址存在负载均衡器。
  • 服务器端维护负载均衡服务器,控制负载均衡策略和算法。

客户端负载均衡器

当负载均衡器位于 客户端 时,客户端得到可用的服务器列表然后按照特定的负载均衡策略,分发请求到不同的 服务器 。

  • 客户端需要知道服务器端的服务列表(可能通过配置、可能让其自己去注册中心拉取),需要自行决定请求要发送的目标地址。
  • 客户端维护负载均衡服务器,控制负载均衡策略和算法。

目前单独提供的客户端实现比较少( 我用过的只有Ribbon,貌似它是现行的唯一实现?),大部分都是在框架内部自行实现(比如Dubbo)。


孰优孰劣?

客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置,服务端属于集中式,客户端属于分布式,孰优孰劣不好比,只能说各有优劣。


Netflix Ribbon

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon-core</artifactId>
    <version>2.7.17</version>
</dependency>

Ribbon(2.7.17版,2019.5发布)已经足够稳定,可运用于大规模生产环境。它的依赖也非常简约:

小细节:截图中可以看到它的依赖大都是runtime的,并不是compile的哦,所以你若想编译期就想用相关API,需要自己导包

Ribbon是一个经过云测试的客户端库。它提供了以下特性

  • Load balancing 负载均衡
  • Fault tolerance 故障容错
  • 异步和响应模型中支持多个协议(HTTP、TCP、UDP)
  • 缓存和批处理

版本声明

看到如上依赖截图,也许你会想问,为何此处没有依赖Archaius这个配置库呢?

这便是这里需要特别声明的地方:Ribbon自2.4.0版本起就不强依赖于Archaius这个库,但是,但是,但是Spring Cloud哪怕到了2020-03-15最新的Hoxton.SR3版本(对应的spring-cloud-starter-netflix-ribbon2.2.2.RELEASE版本),它依赖Ribbon的依旧是2.3.0(2018.4发布),该版本的依赖如下:

它是强依赖于Archaius的,从而很方便的实现了配置动态化,且默认的配置管理API是DefaultClientConfigImpl该API在2.4.0(含)版本后就去掉了,因为并不再强依赖于Archaius库。

鉴于Spring Cloud到现在依旧依赖的Ribbon版本仍旧是2.3.0,并且大概率不会改变(而是着手使用新产品去替代)。本着“Spring优先”原则,在此处对Ribbon版本做出约定:本系列Ribbon使用的版本号是**2.3.0**,版本号是**2.3.0**,是**2.3.0**


关键组件

  • ServerList:可以响应客户端的特定服务的服务器列表
  • ServerListFilter:可以动态获得的具有所需特征的候选服务器列表的过滤器
  • ServerListUpdater:用于执行动态服务器列表更新
  • IRule:负载均衡策略,用于确定从服务器列表返回哪个服务器
  • IPing:客户端用于快速检查服务器当时是否处于活动状态(心跳检测)
  • ILoadBalancer:负载均衡器,负责负载均衡调度的管理

说明,以上核心组件所在的Jar其实是ribbon-loadbalancer,它包含ribbon-core,更面向于应用层面,所以一般都会使用它。


Modules模块

  • ribbon-core:客户端配置api和其他共享api
  • ribbon-loadbalancer:可以独立使用或与其他模块一起使用的负载均衡器api
  • ribbon:集成了负载平衡、容错、缓存/批处理等功能的api
  • ribbon-eureka:使用Eureka客户端为云提供动态服务器列表的api(和自己家的eureka天然整合)
  • ribbon-httpclient:REST客户端构建在Apache HttpClient之上,与负载平衡器集成(不支持并被ribbon模块取代)
  • ribbon-transport:使用具有负载平衡功能的RxNetty传输支持HTTP、TCP和UDP协议的客户端

项目状态(各模块状态)

Project Status: On Maintenance(维护状态)。说明:维护比停更还是要活跃些的。

Ribbon由多个组件组成,其中一些组件用于内部生产,另一些组件随着时间的推移被非oss解决方案所取代。这是因为Netflix开始转向面向RPC的更组件化的体系结构,并将重点放在单一职责模块上。因此,此时每个Ribbon组件都得到了不同程度的关注,具体列出如下:

  • ribbon-core: deployed at scale in production(在生产中大规模部署)
  • ribbon-loadbalancer:deployed at scale in production
  • ribbon-eureka:deployed at scale in production
  • ribbon:not used
  • ribbon-transport:not used
  • ribbon-evcache:not used
  • ribbon-guice:not used
  • ribbon-httpclient:基本同not used

还好的是,它的最核心功能:loadbalancer还是在被大规模使用中的,其它的,无所谓喽。

官方团队有话说: 即使对于在生产环境中部署的组件,我们也将它们封装在Netflix内部http客户端中,并且我们不会添加新的功能,因为它们已经稳定了一段时间。任何新功能都已经添加到Ribbon上的内部包装器中(例如请求跟踪和度量)。我们还没有努力使那些组件在Ribbon下与netflix无关。

认识到这些现实和缺陷,我们将Ribbon设置为维护模式。这意味着如果外部用户提交了一个大的特性请求,我们在内部不会对其进行优先级排序。但是,如果有人要自己完成工作并提交完整的pull requests,我们很乐意进行审查并接受。我们的团队已经开始在gRPC上构建RPC解决方案。我们进行这种转换主要有两个原因:多语言支持和通过请求拦截器实现更好的可扩展性/可组合性。这就是我们目前的计划。

我们目前定期向gRPC代码库贡献代码。为了帮助我们的团队在生产环境中迁移到基于grpc的解决方案(并对其进行实战测试),我们还添加了负载平衡和发现拦截器,以实现与Ribbon和Eureka提供的功能相同的功能。拦截器目前是netflix内部的。当我们达到那种信心水平时,我们希望开放这个新方法。我们预计在2016年第三季度之前不会出现这种情况。


Ribbon和Spring-Cloud-Loadbalancer

Ribbon宣布维护状态的时候,Spring Cloud“心急如麻”,想自研一个工程来代替它,这便是Spring-Cloud-Loadbalancer项目,它的官网:https://github.com/spring-cloud-incubator/spring-cloud-loadbalancer

可以简述Spring-Cloud-Loadbalancer的发展史:

  1. 2017年spring 开始尝试开发新的项目 spring-cloud-loadbalancer 替代ribbon,项目托管在spring-cloud-incubator孵化器

    1. spring cloud alibaba 等顶级的项目大多从此孵化出来的,代表着 spring cloud 的发展方向
  2. 经过N个月的不维护,还以为spring 放弃此项目的时候,突然把此项目标记成归档迁移到spring-cloud-commons了

  3. 之后便随着spring-cloud-commons工程的版本号一起发布而发布

Spring Cloud Hoxton.RELEASE(2019.12月发布)是第一个包含阻塞式和非阻塞式负载均衡器客户端实现的版本,作为已进入维护模式的Netflix Ribbon的替代方案


功能对比

Spring Cloud提供的对负载均衡的支持功能位于spring-cloud-commons这个工程里。你可以参考官方文档相关章节内容:电梯直达

Spring Cloud自己的负载均衡接口是:ReactiveLoadBalancer,总体来说成熟度还不够,离大规模商用部署仍有一段距离。 而至于抽象的通用接口org.springframework.cloud.client.loadbalancer.LoadBalancerClient,它目前的唯一实现仍然仅有RibbonLoadBalancerClient,也就是基于Ribbon的实现。

因此,综合来说他俩还没有什么可以对比的,Ribbon依然坚挺,一时间难有替代方案,所以哪怕到了2020年了,学习Ribbon依旧有非常重要的现实意义。


总结

关于源生Ribbon就先介绍到这,它作为客户端负载均衡器,到目前为止在微服务领域还没有一个可替代的产品,所以虽然它的项目状态已是维护状态,但是学习它还是蛮有现实意义的。因此开展此专列,彻底了解下它的工作流程以及原理、源码解释。

以上是关于源生Ribbon介绍 --- 客户端负载均衡器 - 01的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud无介绍快使用,Ribbon负载均衡工具与OpenFeign的使用(十五)

负责均衡-手写简单的负载均衡和ribbon介绍

7-2 负载均衡及Ribbon介绍

Ribbon负载均衡和调用

服务消费者(Feign)和负载均衡(Ribbon)使用详解

springcloud-Ribbon负载均衡服务调用