Ribbon源码系列——客户端负载均衡与LoadBalanced注解
前言
这篇文章,笔者开始研究新的系列啦,也就是标题里的Ribbon系列源码🤓。
之前的Eureka系列分了十篇讲解,但是阅读量好低,应该不是博客园的原因吧🤡。
客户端负载均衡
Ribbon和前面研究的Eureka组件不太一样,他不需要独立部署,而是依附于客户端应用,随着客户端一起部署。在调用方客户端向外发起请求的时候,代理发起请求的操作,为调用方选择一个合理的提供方实例。
负载均衡与服务实例
我们之前接触到的负载均衡,一般都是在说服务端负载均衡,服务端负载均衡有硬件和软件之分,不过原理是类似的,有感兴趣的同学可以自行了解一下。凡是具备负载均衡功能的组件,都需要维护服务实例注册表,要能感知到所有服务实例的状态,才能通过实例的健康度和自定义配置来进行请求的负载均衡。通常通过keep-alive等心跳机制保持与服务实例的通信
“顺手牵羊”注册表
注册表?听着那么熟悉呢。嗷,Eureka已经为我们维护了现成的注册表和服务实例状态,更贴心的是,还维护了客户端的缓存注册表。作为负载均衡的组件,我们只要借用Eureka的这套实现就可以啦!
并且既然已经有客户端的缓存注册表了,那我们不如将计就计,不在服务端做负载均衡,而是改成:在客户端发起调用的时候,对服务提供方的实例进行负载均衡,这样就能利用上客户端本地的缓存注册表了
Ribbon的入口
Ribbon依赖于Spring的RestTemlate,所以笔者先简单介绍一个RestTemplate。
RestTemplate
RestTemplate是Spring提供的对 同步Http请求 的统一模板类,通过模板类,开发者可以不再对具体Http请求的实现手段进行编程,而是面向RestTemplate的API编程。如果有替换具体Http实现的需求,也不需要改应用中的调用点了,只要具体Http实现对RestTemplate适配即可。
说个题外话,这种“多加一层”的解决方案在计算机领域随处可见,他有很多名字:面向接口编程,依赖反转等等,其实说的都是这种思想。
出处是图灵奖得主Butler Lampson的名言:All problems in computer science can be solved by another level of indirection
@LoadBalanced注解入口
Ribbon的使用非常简单,只要在RestTemplate的Bean声明上加一个@LoadBalanced
注解就可以,像这样:
@LoadBalanced//Ribbon入口
RestTemplate restTemplate(){
return new RestTemplate();
}
那么Ribbon的入口显然就是这个@LoadBalanced
注解了,我们来看一下这个注解的源码:
@Qualifier注解的新奇用法
注解的源码清晰的令人惊讶,这个注解只是一个标记注解,只有一个@Qualifier
注解比较特别,对Spring有一定了解的读者都应该知道这个注解,简单来说就是当Bean定义有多个时,通过在属性上使用@Qualifier
限定符注解,来将指定的Bean注入进来。
那在这里@Qualifier
注解有什么用呢,其实这是一种特殊的用法,笔者也是第一次见到,感觉还挺酷的🆒。简单描述就是被@Qualifier
修饰的注解,用在Bean的声明上,这样可以在后续注入这个类型的Bean的时候,只注入被@Qualifier
修饰的那些Bean,没有被修饰的Bean不会被注入。
Ribbon对@LoadBalanced的处理
下面我们看看Ribbon是怎么处理我们用了@LoadBalanced
修饰的RestTemplate。
我们来全局搜索@LoadBalanced
注解,发现在LoadBalancerAutoConfiguration
有使用:
结合我们上文对@Qualifier
注解的认识,我们就明白了,红框里的代码,会将我们应用中手动使用@LoadBalanced
注解修饰的RestTemplate
注入进来,其他没有被@LoadBalanced
修饰的RestTemplate不会被注入。
下集预告
这篇文章主要是介绍了Ribbon的基本使用,并且找到了Ribbon源码的入口,下一篇文章将正式开始进入Ribbon源码的学习。
Over🐾