SpringCloud系列之负载均衡Ribbon·7-负载均衡器
前面我们学习了Ribbon的7种内置负载均衡策略,那么大家知道是谁在这中间牵线搭桥,把配置的负载均衡策略“加塞”到一个HTTP请求的调用链路里的吗?这就要讲到Ribbon对RestTemplate的改造。
之前我们搭建了自己的ribbon-consumer,大家都知道Ribbon通过RestTemplate来发起调用请求。可是,RestTemplate分明是spring-web包下的通用类,它诞生的时候Ribbon还不知道在哪儿呢,那Ribbon是如何实现偷天换日,悄悄把自己“加塞”到RestTemplate中去的呢?
@LoadBalanced注解,它会将RestTemplate传送到Ribbon的自动装配类里进行改造。
@LoadBalanced 这个注解一头挂在RestTemplate上,另一头挂在LoadBalancerAutoConfiguration这个类上。它就像连接两个世界的传送门,将所有顶着「LoadBalanced」注解的RestTemplate类,都传入到LoadBalancerAutoConfiguration中。如果要深挖底层的作用机制,大家可以发现这个注解的定义上还有一个@Qualifier注解,可能对Spring比较熟悉的同学就恍然大悟了。@Qualifier注解搭配@Autowired注解做自动装配,可以通过name属性,将指定的Bean装载到指定位置(即使有两个同样类型的Bean,也可以通过Qualifier定义时声明的name做区分)。这里「LoadBalanced」也是借助Qualifier实现了一个给RestTemplate打标签的功能,凡是被打标的RestTemplate都会被传送到AutoConfig中做进一步改造。
LBAutoConfig 从前一步中传送过来的RestTemplate,会经过LBAutoConfig的装配,将一系列的Interceptor(拦截器)添加到RestTemplate中。拦截器是类似职责链编程模型的结构,我们常见的ServletFilter,权限控制器等,都是类似的模式。Ribbon拦截器会拦截每个网络请求做一番处理,在这个过程中拦截器会找到对应的LoadBalancer对HTTP请求进行接管,接着LoadBalancer就会找到默认或指定的负载均衡策略来对HTTP请求进行转发。
总结Ribbon的作用机制就是,由LoadBalanced在RestTemplate上打标,Ribbon将带有负载均衡能力的拦截器注入标记好的RestTemplate中,以此实现了负载均衡。在稍后的源码阅读章节,将带大家深入研究LoadBalanced注解的作用机制。
IPing机制
在计划生育实施的初期,效果并不好,因为那时候没有如今各种丰富的娱乐活动,大家下了班都闲着没事干,闲着没事那就只好造人了。后来有个村支书想了个法子,他给每家配了一台电视机,这样一来每家每户晚上就有事情可干了,超生指标立马就降下来了。这说明了一个问题,闲着没事就得要找点事干。
Ribbon也正面临这么个问题,和其它SpringCloud组件相比,Ribbon可谓称得上闲差,因为它的职责相对单一,只应用在负载均衡方面,说明它太闲了,所以这才要给Ribbon找点事儿干。
IPing机制就是SpringCloud发给Ribbon家的电视机,那它放哪些电视节目呢?现在请收看电视节目《撩妹指南》
IPing是一个主动出击撩妹子的机制,他主动判断服务节点的当前状态,决定是否可作为目标节点,只有当前可用的节点才会作为负载均衡器的目标节点。IPing有以下几个撩妹手段:
- 自娱自乐式:DummyPing,默认返回true,即认为所有节点都可用,这也是单独使用Ribbon时的默认模式
- 隔山打牛式:NIWSDiscoveryPing,借助Eureka服务发现机制获取节点状态,假如节点状态是UP则认为是可用状态
- 主动出击式:PingUrl,这才是真正走出家门去撩妹,它会主动向服务节点发起一次http调用,如果对方有响应则认为节点可用
大家可以看出第三种主动出击的模式比较生猛,IPing就像一条脱缰的野狗一样,对每个服务节点撩个不停,节点们纷纷表示扛不住扛不住。大家可以想象,假如我们的服务节点搭载的是淘宝ump服务(负责计算商品、购物车与订单优惠,淘系top5调用量),ump下随便一个微服务都有大几千台服务器,在服务本身就被超高访问量调用的情况下,那这种主动出击的IPing策略必然会大大增加服务节点的访问压力。
既然Eureka已经有了服务发现机制,可以获取节点的当前状态,拿来就用岂不更好?因此,除非特殊指定,在和Eureka搭配使用的时候,采用的是第二种隔山打牛式,也就是过滤非UP状态的节点(其实这个功能直接放Eureka里也能做。。。看来真的是没事给Ribbon找点事)