目录
Ribbon是什么
Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡器。它扩展了 Eureka 客户端 的服务发现功能,能够从 Eureka 注册中心 获取服务端列表,并通过 Eureka 客户端确定服务端是否已启动。Ribbon 在服务发现的基础上,实现了对服务实例的选择策略,从而支持对服务的负载均衡消费。
负载均衡的重要性
负载均衡 是系统架构中非常重要的内容,主要用于:
提高系统的 高可用性。
缓解网络压力。
扩展系统的处理能力。
负载均衡的分类:
服务端负载均衡:
硬件负载均衡:通过专门的负载均衡设备(如 F5、Array 等)实现。
软件负载均衡:通过安装负载均衡软件(如 Nginx、LVS、HAProxy 等)实现。
客户端负载均衡:由客户端实现负载均衡,如 Ribbon。
Ribbon 的核心功能
服务清单维护:
硬件或软件负载均衡设备会维护一个可用的服务端清单,并通过心跳检测剔除故障节点。
当客户端发送请求时,负载均衡设备会按某种算法(如轮询、权重、流量等)从清单中选择一个服务端地址进行转发。
Ribbon 的特点:
Ribbon 是 Netflix 发布的开源项目,提供 客户端负载均衡算法。
Spring Cloud 对 Ribbon 进行了二次封装,使其能够与 RestTemplate 结合使用,自动实现客户端负载均衡。
支持多种负载均衡算法,并允许自定义算法。
Ribbon 是一个轻量级框架,无需独立部署,直接在代码中使用即可。
Ribbon 与 Nginx 的区别
服务清单存储位置:
Ribbon:客户端从服务注册中心(如 Eureka)获取服务清单。
Nginx:服务端维护服务清单。
负载均衡位置:
Ribbon:客户端负载均衡。
Nginx:服务端负载均衡。
健康检查:
Ribbon 需要与服务注册中心(如 Eureka)配合,通过心跳机制维护服务清单的健康性。
Spring Cloud 中的 Ribbon
自动化配置:
Spring Cloud 默认为 Ribbon 提供了自动化整合配置(如 `RibbonEurekaAutoConfiguration`)。
可以通过查看相关配置类了解具体实现细节。
使用步骤:
1. 服务提供者启动多个实例并注册到注册中心(如 Eureka)。
2. 服务消费者通过 `@LoadBalanced` 注解修饰的 `RestTemplate` 实现面向服务的接口调用。
优势:
通过 Ribbon 和 RestTemplate 的结合,可以轻松实现服务提供者的高可用性和服务消费者的负载均衡。
Ribbon实现客户端负载均衡
EurekaClientMinor
我们将EurekaCilent复制一份出来,只修改application.yml和controller返回内容:
server:
port: 7005
spring:
application:
name: EurekaClient
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:7001/eureka
instance:
lease-renewal-interval-in-seconds: 1 #间隔1s,向服务端发送一次心跳,证明自己依然“存活”
lease-expiration-duration-in-seconds: 2 # 告诉服务端,如果我2s之内没有给你发心跳,就代表我“死”了,请将我踢掉
@RestController
@RequestMapping("/client")
public class ClientController {
@RequestMapping("/hello")
public String hello(){
return "hello eureka client minor";
}
}
然后启动。
可以看到client提供了两个实例:
这个时候我们重启EurekaTest,然后访问127.0.0.1:7003/test/hello,不断刷新,可以看到:
EurekaClient和EurekaClientMinor交替出现,说明默认轮询策略。
Ribbon负载均衡策略
Ribbon的负载均衡策略是由IRule接口定义,该接口由如下实现:
IRule 实现类的负载策略含义
`RandomRule` (随机策略)
含义:随机选择一个服务实例。
适用场景:适用于负载分布相对均匀的场景。
`RoundRobinRule` (轮询策略)
含义:按照顺序循环选择服务实例。
适用场景:适用于需要均匀分发请求的场景。
`AvailabilityFilteringRule` (可用性过滤策略)
含义:先过滤掉由于多次访问故障的服务,以及并发连接数超过阈值的服务,然后对剩下的服务按照轮询策略进行访问。
适用场景:适用于需要优先选择可靠服务实例的场景。
`WeightedResponseTimeRule` (加权响应时间策略)
含义:根据平均响应时间计算所有服务的权重,响应时间越快服务权重就越大,被选中的概率即越高。如果服务刚启动且统计信息不足,则使用 `RoundRobinRule` 策略;待统计信息足够后,会切换到该 `WeightedResponseTimeRule` 策略。
适用场景:适用于需要根据性能动态调整负载的场景。
`RetryRule` (重试策略)
含义:先按照 `RoundRobinRule` 策略分发,如果分发到的服务不能访问,则在指定的时间内重试;如果重试失败,则分发到其他可用的服务。
适用场景:适用于网络不稳定或服务实例偶尔不可用的场景。
`BestAvailableRule` (最佳可用策略)
含义:先过滤掉由于多次访问故障的服务,然后选择一个并发量最小的服务。
适用场景:适用于需要减少某个服务实例连接数的场景。
`ZoneAvoidanceRule` (区域感知策略)
含义:综合判断服务节点所在区域的性能和服务节点的可用性,来决定选择哪个服务。
适用场景:适用于分布式部署场景,可减少跨区域的网络延迟。
结合Ribbon负载均衡,默认的是轮询,重新注入IRule可以实现负载均衡的其他策略
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced //加入ribbon的支持,那么在调用时,即可改为使用服务名称来访问
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public IRule iRule(){
RetryRule retryRule = new RetryRule();
retryRule.setMaxRetryMillis(500);
return retryRule;
}
}