Ribbon负载均衡器
什么是Ribbon?
-
Ribbon是Netflix发布的负载均衡器,有助于控制HTTP客户端行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于负载均衡算法,自动帮助服务消费者请求。
-
Ribbon默认提供的负载均衡算法:轮询,随机,重试法,加权。当然,我们可用自己定义负载均衡算法
案例入门
1.环境配置
- 用集群的方式创建两个springboot子工程,并且注册到Eureka注册中心
- 生产者目录结构
- user_provider的application.yml的配置文件端口号为18081,user_provider_demo1则是18083
server:
port: 18081 #user_provider_demo1则是18083
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://127.0.0.1:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
application:
name: user-provider #服务的名字,不同的应用,名字不同,如果是集群,名字需要相同
#指定eureka服务地址
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
- 两个生产者启动,注册发现到Eureka,访问eureka-server地址http://127.0.0.1:7001/ 效果如下:
2.开启负载均衡
- 消费者结构
- UserController直接通过服务名称调用,代码如下:
- 为了区别是否负载均衡,我们在两个生产者controller添加了字段区别
- 访问http://localhost:18082/consumer/1测试发现。
第一次访问是
刷新访问第二次
- Ribbon默认的负载均衡策略是轮询,我们可以修改配置文件改变
- SpringBoot可以修改负载均衡规则,配置为ribbon.NFLoadBalancerRuleClassName
格式:{服务名称}.ribbon.NFLoadBalancerRuleClassName
在消费者中配置文件添加以下代码:
# 修改服务地址轮询策略,默认是轮询,配置之后变随机
user-provider:
ribbon:
#轮询
#NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
#随机算法
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
#重试算法,该算法先按照轮询的策略获取服务,如果获取服务失败则在指定的时间内会进行重试,获取可用的服务
#NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule
#加权法,会根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越大。刚启动时如果同统计信息不足,则使用轮询的策略,等统计信息足够会切换到自身规则。
#NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule
负载均衡源码跟踪探究
为什么只输入了Service名称就可以访问了呢?不应该需要获取ip和端口吗?
负载均衡器动态的从服务注册中心中获取服务提供者的访问地址(host、port)
显然是有某个组件根据Service名称,获取了服务实例ip和端口。就是LoadBalancerInterceptor
这个类会对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,随后利用负载均衡算法得到真正服务地址信息,替换服务id。
总结:负载均衡的切换:在LoadBalancerInterceptor中获取服务的名字,通过调用RibbonLoadBalancerClient的execute方法,并获取ILoadBalancer负载均衡器,然后根据ILoadBalancer负载均衡器查询出要使用的节点,再获取节点的信息,并实现调用