Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它是基于 Netflix Ribbon 实现的。
它不想 Spring Cloud 服务注册中心、配置中心、API网关那样独立部署,但是它几乎存在于每个Spring Cloud 微服务中。包括 Feign 提供的声明式服务调用也是基于该 Ribbon 实现的。
Ribbon 默认提供很多种负载均衡算法,例如轮询、随机等等,甚至包含自定义的负载均衡算法。
2、Ribbon 解决了什么问题?Ribbon 提供了一套微服务的负载均衡解决方案。
3、负载均衡不同方案的区别目前业界主流的负载均衡方案可分成两类:
- 集中式负载均衡(服务器负载均衡),即在 consumer 和 provider 之间使用独立的负载均衡设施(可以是硬件,如 F5,也可以是软件,如Nginx),由该设施负责把访问请求通过某种策略转发至 provider;
- 进程内负载均衡(客户端负载均衡),将负载均衡逻辑继承到 consumer,consumer 从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的 provider。
Ribbon 属于后者,它只是一个类库,集成于 consumer 进程,consumer 通过它来获取 provider 的地址。
3.1、集中式负载均衡 3.2、进程内负载均衡 4、Ribbon 负载均衡策略 4.1、轮询策略(默认)策略对应类名:RoundRobinRule
实现原理:轮询策略表示每次都顺序取下一个 provider,比如一共有 5 个 provider,第1次取第1个,第2次取第2个,第3次取第3个,以此类推。
4.2、权重轮询策略策略对应类名:WeightedResponseTimeRule
实现原理:
- 根据每个 provider 的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性越小。
- 原理:一开始为轮询策略,并开启一个计时器,每 30 秒收集一次每个 provider 的平均响应时间,当信息足够时,给每个 provider 附上一个权重,并按权重随机选择 provider,越高权重的 provider 会被高概率选中。
策略对应类名:RandomRule
实现原理:从 provider 列表中随机选择一个。
4.4、最少并发数策略策略对应类名:BestAvailableRule
实现原理:选择正在请求中的并发数最小的 provider,除非这个 provider 在熔断中。
4.5、重试策略策略对应类名:RetryRule
实现原理:其实就是轮询策略的增强版,轮询策略当服务不可用时不做处理,而重试策略在服务不可用时会重新尝试集群中的其他节点。
4.6、可用性敏感策略策略对应类名:AvailabilityFilteringRule
实现原理:过滤性能差的 provider
- 第一种:过滤掉在 Eureka 中处于一直连接失败的 provider
- 第二种:过滤掉高并发(繁忙)的 provider
策略对应类名:ZoneAvoidanceRule
实现原理:
- 以一个区域为单位考察可用性,对于不可用的区域整个丢弃,从剩下区域中选可用的 provider
- 如果这个 ip 区域内有一个或多个实例不可达或响应变慢,都会降低该 ip 区域内其他 ip 被选中的权重
在笔者的前几篇文章中,我们建立了 eureka-demo,那么我们就基于这个案例项目对 Ribbon 进行学习。
我们在 eureka-demo 项目中创建子项目 server-provider02,与之前的项目一样:
添加依赖
4.0.0 service-consumer 1.0-SNAPSHOT org.fengluo eureka-demo 1.0-SNAPSHOT service-consumer http://www.example.com UTF-8 1.7 1.7 org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine maven-clean-plugin 3.1.0 maven-resources-plugin 3.0.2 maven-compiler-plugin 3.8.0 maven-surefire-plugin 2.22.1 maven-jar-plugin 3.0.2 maven-install-plugin 2.5.2 maven-deploy-plugin 2.8.2 maven-site-plugin 3.7.1 maven-project-info-reports-plugin 3.0.0
添加配置文件(注意修改一下端口,我这边修改成了7071)
server:
port: 7071 # 端口
spring:
application:
name: service-provider # 注册名称
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true # 是否使用 ip 地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
client:
service-url: # 设置服务注册中心地址
defaultZone: http://root:123456@localhost:8761/eureka/,http://root:123456@localhost:8762/eureka/
# 度量指标监控与健康检查
management:
endpoints:
web:
exposure:
include: shutdown # 开启 shutdown 访问
endpoint:
shutdown:
enabled: true # 开启 shutdown 实现停服
将 server-provider 中的服务以及启动类复制过来即可!
这里注意我们为了观察负载均衡机制的效果,采用了第二种方法,即通过客户端负载均衡获取服务,并打印访问的 provider 的 ip 地址和端口号,并关闭了启动类的 负载均衡注解!
@Override
public Order selectOrderById(Integer id) {
return new Order(id, "order-001", "中国", 31994D,
selectProductListByLoadBalancerClient());
}
………
sb = new StringBuffer();
sb.append("http://" + si.getHost() + ":" + si.getPort() + "/product/list");
System.out.println(sb);
启动注册中心
最后我们启动消费者,并多次访问 http://localhost:9090/order/1,可以看到访问的 ip,即 Ribbon 的默认负载均衡策略,轮询。



