外观
02.Spring Cloud Netfilx Ribbon:负载均衡工具
一、Spring Cloud Netfilx Ribbon简介
1. Ribbon简介
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。 Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要学习的OpenFeign,它也是基于Ribbon实现负载均衡的远程服务调用工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。 简单来说,Ribbon就是SpringCloud提供的一个负载均衡的工具,从Eureka Server中获取到的某个服务的多个地址信息,通过Ribbon可以实现负载均衡!而且它不像Eureka Server那样需要独立部署。
2. Ribbon执行原理

2.1 原理说明
所有的微服务项目都会注册到Eureka Server中,Eureka Server允许不同项目的应用名称即spring.application.name是相同。当应用名称相同时会认定这些项目是一个集群。所以部署集群时都是设置相应的应用程序相同的应用名称。 Application Client会从Eureka Server中根据spring.application.name加载Application Service的列表。根据设定的负载均衡算法,从列表中取出一个合适的URL,到此Ribbon的事情结束了。剩下的事情由程序员自己进行技术选型,选择一个HTTP协议工具(如:RestTemplate、OkHttp、HttpClient等),通过这个URL远程调用Application Service服务。 注意:以下事情和Ribbon是没有关系的 Application Service注册到Eureka Server的过程。这是Eureka Client的功能。 Application Client从Eureka Server中发现注册列表。这是Eureka Client的功能。 Application Client通过URL远程访问Application Service。具体实现可以自己进行选择使用哪个HTTP工具。 只有Application Client从Eureka Server中发现服务后进行负载均衡算法的过程和Ribbon有关系。 2.2****负载均衡器继承关系 LoadBalancer 负载均衡的意思,简称LB


二、负载均衡解决方案分类及特性 业界主流的负载均衡解决方案有:集中式负载均衡和进程内负载均衡。 1****集中式负载均衡 即在客户端和服务端之间使用独立的负载均衡设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务端。也叫做:服务器端负载均衡。

2****进程内负载均衡 将负载均衡逻辑集成到客户端组件中,客户端组件从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务端发起请求。Ribbon就是一个进程内的负载均衡实现。也叫做:客户端负载均衡。

三、搭建Application Service集群 前提:已经配置了单机版Eureka。且端口为8761。 新建项目ApplicationService 1****POM依赖2****编写配置文件 编写application.yml配置文件 3****编写控制器 编写com.lhp.controller.TestController类: 4****编写启动类型 编写启动类型 com.lhp.ApplicationServiceApp 5****启动项目 基于不同的端口,启动三次项目。分别修改控制器中的数字后缀和配置文件中的端口号。搭建本地伪集群。


四、基于Ribbon测试负载均衡1****说明 上面的案例中,我们搭建好了Eureka Server,可以让各种服务进行注册; 搭建好了application service的集群,有3个节点的集群,要求他们的application name必须一样。 接下来我们创建一个application client,让它从Eureka Server上获取到application service的信息列表,然后通过Ribbon的负载均衡从获取到的application service的信息列表中选择一个我们要调用的! 但是我们先不调用application service,因为目前我们还没有学习通过什么工具调用!
所以下面的案例,就是演示确实通过Ribbon负载均衡技术可以从一个服务列表中选择一个节点进行后续的调用! 2****搭建Application Client工程 创建工程Application Client。 3****POM依赖4****编写配置文件 编写application.yml配置文件 5****编写服务接口和实现5.1****编写服务接口 com.lhp.service.ApplicationClientService5.2****编写服务实现 com.lhp.service.impl.ApplicationClientServiceImpl6****编写控制器 编写com.lhp.controller.ApplicationClientController 7****编写启动类型 编写启动类型 com.lhp.ApplicationClientApp 8****测试 启动应用。并多次访问 client 服务。观察控制台输出结果。 可以发现通过Ribbon负载均衡确实可以从多个服务端的地址中选出一个要访问的地址,多刷新几次,发现使用的负载均衡算法是轮询! 五、Spring Web 之 RestTemplate 基于Http协议的远程访问RestTemplate是spring-web-xxx.jar包中提供的Http协议实现类。也就是说导入spring-boot-starter-web的项目可以直接使用RestTemplate。在该类中提供针对6类请求方式的模板方法。 通过RestTemplate可以实现服务之前的调用,比如A服务通过RestTemplate调用B服务的方法! 接下来我们就准备两个工程,名称分别是service1、service2,在service1中写个controller方法,在service2中写个controller方法,然后在service2的controller方法中通过restTemplate远程调用service1中controller方法! 1****创建服务工程1 创建服务工程1,名称是service1 1.1****POM依赖1.2****编写配置文件 编写配置文件application.yml 1.3****编写控制器 编写控制器 com.lhp.controller.Service1Controller 1.4****编写启动类型 编写启动类型 com.lhp.Service1Application 1.5****启动服务 启动应用 2****创建服务工程2 创建测试工程,名称是service2 2.1****POM依赖2.2****编写配置文件 编写配置文件application.yml 2.3****编写控制器 编写控制器 com.lhp.controller.Service2Controller 2.4****编写启动类型 编写启动类型 com.lhp.Service2Application 2.5****启动服务 启动应用,访问service2中的方法,可以看到远程调用service1中方法成功! 六、基于RestTemplate和Ribbon实现Application Client调用Application Service集群 修改工程Application Client,基于RestTemplate实现远程服务调用。 1****编写配置类型 创建com.lhp.config.AppClientConfiguration 2****修改服务实现 com.lhp.service.impl.ApplicationClientServiceImpl3****测试 重启Application Client应用,访问测试,观察远程服务调用结果(可能得稍等一会才能看到负载均衡的效果,可以先试试每个服务提供者都能访问不)。 七、Ribbon负载均衡算法 Ribbon的负载均衡策略是通过不同的类型来实现的(都是IRule接口的实现),下表详细介绍一些常用负载均衡策略及对应的Ribbon策略类。
| 编号 | 策略名称 | 策略对应的类名 | 实现原理 |
|---|---|---|---|
| 1 | 轮询策略(默认) | RoundRobinRule | 轮询策略表示每次都按照顺序取下一个application service,比如一共有5个application service,第1次取第1个,第2次取第2个,第3次取第3个,以此类推 |
| 2 | 权重轮询策略(常用,中小型项目使用) | WeightedResponseTimeRule | 1.根据每个application service的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越低。 2.原理:一开始为轮询策略,并开启一个计时器,每30秒收集一次每个application service的平均响应时间,当信息足够时,给每个application service附上一个权重,并按权重随机选择application service,权重越高的application service会被高概率选中。 |
| 3 | 随机策略(不推荐,测试使用,开发使用) | RandomRule | 从application service列表中随机选择一个 |
| 4 | 最少并发数策略(应用在硬件软件环境一致的情况下,中小型项目使用) | BestAvailableRule | 选择正在请求中的并发数最小的application service,除非这个application service在熔断中。 |
| 5 | 重试策略。在“选定的负载均衡策略”基础上进行重试机制 | RetryRule | 1.“选定的负载均衡策略”这个策略是轮询策略RoundRobinRule 2.该重试策略先设定一个阈值时间段,如果在这个阈值时间段内当选择application service不成功,则最后会选择一个可用的application service |
| 6 | 可用性敏感策略(一般在同区域内服务集群环境中使用) | AvailabilityFilteringRule | 过滤性能差的application service,有2种: 第一种:过滤掉在eureka中处于一直连接失败application service 第二种:过滤掉高并发的application service |
| 7 | 区域敏感性策略(应用在大型的,物理隔离分布式环境中) | ZoneAvoidanceRule | 1.以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的application service 2.如果这个ip区域内有一个或多个实例不可达或响应变慢,都会降低该ip区域内其他ip被选中的权重。 |
八、指定负载均衡策略1修改配置类型 修改类型com.lhp.config.AppClientConfiguration,新增Bean对象管理方法
@Bean
public IRule iRule(){
return newRandomRule();
}
2测试 重启Application Client应用,观察负载均衡策略。