文章目录
- 5. Ribbon负载均衡
- 5.1 Ribbon概念
- 5.2 Ribbon的入门案例
- 5.2.1 启动服务提供者
- 5.2.2 启动服务消费者
- 5.2.2.1 开启负载均衡[@LoadBalanced]
- 5.2.2.2 修改调用服务的方式
- 5.2.2.3 测试
- 5.3 原理分析
- 5.4 负载均衡策略
- 5.4.1 默认策略
- 5.4.2 修改策略配置
5. Ribbon负载均衡
在Eureka的入门案例中,我们启动了一个user_service,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。但是实际环境中,我们往往会开启很多个user_service的集群。此时我们获取的服务列表中就会有多个,到底该访问哪一个呢?
一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。不过Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。
5.1 Ribbon概念
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者的地址列表后,Ribbon就可以基于某种负载均衡算法,自动地帮助服务消费者去请求。
Ribbon默认为我们提供了很多负载均衡的算法,例如轮询、随机等。当然,我们也可以为Ribbon实现自定义的负载均衡算法。
5.2 Ribbon的入门案例
接下来,我们就来使用Ribbon实现负载均衡。
这里注意,SpringCloud的版本需要使用Greenwich或以下版本,Greenwich以上的版本中,Spring 更新了很多东西,正在逐步替换掉Ribbon的负载均衡。使用的是BlockingLoadBalancerClient ,会在之后学习。
5.2.1 启动服务提供者
以两个服务提供者为例,首先我们启动两个服务提供者。
这里使用之前的user_service(服务提供者,端口是8080)。再在此基础上启动一个8081端口的服务提供者。
- 在user_service中配置端口
# Server Config
server:
port: ${port:8080}
- 修改并添加新的启动配置
- 启动服务实例
- Eureka监控面板
5.2.2 启动服务消费者
这里以Eureka入门案例中的user_call为基础,将其以8082端口启动。
5.2.2.1 开启负载均衡[@LoadBalanced]
因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖。
在 RestTemplate 的配置方法上添加 @LoadBalanced 注解,即可开启负载均衡。
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
5.2.2.2 修改调用服务的方式
修改调用方式,不再手动获取服务列表、ip和端口,而是直接通过服务名称调用。
@RequestMapping(value = "{id}", method = RequestMethod.GET)
public User queryById(@PathVariable("id") Long id) {
String url = "http://user-service/user/"+id;
return restTemplate.getForObject(url, User.class);
}
注意:这里修改之前,需要将user_service的服务名称改成user-service 。
5.2.2.3 测试
5.3 原理分析
之前还要获取ip和端口,为什么现在只拼接服务名称就可以访问了呢?
因为 user_call 使用的是RestTemplate,Spring 使用了LoadBalancerInterceptor拦截器。
- 这个拦截器会在对 RestTemplate 的请求进行拦截;
- 然后从Eureka根据服务名称映射到服务id去获取服务列表,利用负载均衡算法得到真实的服务地址信息,替换服务id;
默认负载均衡策略是轮询(表现形式是IRule的实现类)。
- 执行请求,并返回响应。
再次请求发现,请求服务的端口号变成了8080:
5.4 负载均衡策略
5.4.1 默认策略
在刚才的Ribbon源码中,我们看到拦截中是使用RibbonLoadBalancerClient的实例进行负载均衡的。那么前面说它使用的默认负载均衡策略是轮询,我们可以测试一下:
@Autowired
RibbonLoadBalancerClient client;
@Test
void contextLoads() {
for (int i = 0; i < 100; i++) {
ServiceInstance instance = this.client.choose("user-service");
System.out.println(instance.getHost() + ":" + instance.getPort());
}
}
部分打印输出如下:
上述验证了Ribbon默认的负载均衡策略是简单的轮询。
5.4.2 修改策略配置
SpringBoot也帮我们提供了修改负载均衡规则的配置入口:
# 修改负载均衡规则的配置
user-service: #服务名称
ribbon:
# 修改成随机的方式,值就是IRule的实现类,默认是轮询
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ensp; 部分打印输出如下: