Fork me on GitHub

SpringCloud Ribbon

目录

在之前几篇 Spring Cloud 的 5 分钟指南里我们已经依次介绍了多个 Spring Cloud 的核心组件,其中涵盖了微服务架构中必须的基础功能,例如服务发现,熔断,中心化配置。今天介绍的主角同样是由 Netflix 出品的 Ribbon,官方给 Ribbon 的定义是一个用于远程调用的库,而它更为人熟知的作用是可以进行客户端的 Load Balance。

Load Balance 对于任何一个分布式系统都是必要的基础功能,从实现角度而言,可以分为客户端 LB 和服务器端 LB。在日常工作中大家接触最多的应该是基于服务器的 LB 解决方案,例如通过 nginx 的反向代理,或是商用的 F5。但是今天的例子中会演示如何使用 Ribbon 搭建一个具有 LB 的客户端应用。让我们开始吧。

一般来说,提到负载均衡,大家一般很容易想到浏览器 -> NGINX -> 反向代理多个Tomcat这样的架构图——业界管这种负载均衡模式叫“服务器端负载均衡”,因为此种模式下,负载均衡算法是NGINX提供的,而NGINX部署在服务器端。
本节所讲的Ribbon则是一个客户端侧负载均衡组件——通俗地说,就是集成在客户端(服务消费者一侧),并提供负载均衡算法的一个组件。

Ribbon简介

Ribbon是Netflix发布的负载均衡器,它可以帮我们控制HTTP和TCP客户端的行为。只需为Ribbon配置服务提供者地址列表,Ribbon就可基于负载均衡算法计算出要请求的目标服务地址。
Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机、响应时间加权等——当然,为Ribbon自定义负载均衡算法也非常容易,只需实现IRule 接口即可。
TIPS
Ribbon的GitHub:https://github.com/Netflix/ribbon

引入Ribbon

在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,选择其中一个服务提供者实例。下图展示了Ribbon与Eureka配合使用时的大致架构。
SpringCloud Ribbon

Ribbon入门

代码示例

  • 复制项目microservice-consumer ,将ArtifactId修改为microservice-consumer-ribbon
  • 加依赖:由于spring-cloud-starter-netflix-eureka-client 已经包含spring-cloud-starter-netfilx-ribbon ,故而无需额外添加依赖。

  • 写代码:

1
2
3
4
5
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
  • 如代码所示,只需在RestTemplate 上添加LoadBalanced 注解,即可让RestTemplate整合Ribbon!
  • 调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/ribbon")
@RestController
public class RibbonController {
@Autowired
private RestTemplate restTemplate;

@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
// 这里用到了RestTemplate的占位符能力
User user = this.restTemplate.getForObject("http://microservice-provider/user/{id}", User.class, id);
// User user = this.restTemplate.getForObject("http://microservice-provider-user/users/{id}", User.class, id);
// User user = this.restTemplate.getForObject("http://10.254.193.129:8180/user/{id}", User.class, id);
return user;
}
}
  • 由代码可知,我们将请求的目标服务改成了http://microservice-provider/user/{id},也就是http://{目标服务名称}/{目标服务端点} 的形式,Ribbon会自动在实际调用时,将目标服务名替换为该服务的IP和端口

测试

  • 依次启动microservice-discovery-eurekamicroservice-provider 两个实例、microservice-consumer-ribbon
  • 访问http://localhost:8010/ribbon/user/1 多次,会发现两个user服务实例都会打印日志。

WARNING
事实上,这里的目标服务名称,在Ribbon里叫虚拟主机名 ,主机名是不能包含_ 等特殊字符的——这意味着,一般不建议配置spring.application.name = xxx_xxx ,如果你的应用名称一定(谁这么变态??)带有下划线这种字符,那么请额外配置eureka.instance.virtual-host-name = 一个合法的主机名 ,否则Ribbon将会提示虚拟主机名不合法的异常(在早期的版本则是报空指针)!这点请大家务必注意。

相关文章