0


Ribbon IPing机制源码探秘

🍊 Java学习:社区快速通道

🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想

🍊 绝对不一样的职场干货:大厂最佳实践经验指南

📆 最近更新:2023年7月2日

🍊 点赞 👍 收藏 ⭐留言 📝 都是我最大的动力!


文章目录

IPing机制

  1. Ribbon

会主动判断服务节点的当前状态,决定是否可作为目标节点,只有当前可用的节点才会作为负载均衡器的目标节点。IPing有以下几个手段:

  • DummyPing:默认返回true,即认为所有节点都可用,这也是单独使用Ribbon时的默认模式
  • NIWSDiscoveryPing:借助Eureka服务发现机制获取节点状态,假如节点状态是UP则认为是可用状态
  • PingUrl:主动向服务节点发起一次http调用,如果对方有响应则认为节点可用
  • PingConstant:返回设置的常量值
  • NoOpPing:返回true

假如服务节点搭载的服务本身就承载超高并发的情况下,那这种主动出击的

  1. IPing

策略必然会大大增加服务节点的访问压力。

Ribbon IPing是一个接口,可以通过实现该接口来自定义Ping机制。Ribbon IPing的实现类需要在配置文件或者代码中指定,例如:

  1. #单个服务设置[service-name]:ribbon:NFLoadBalancerPingClassName: com.netflix.loadbalancer.DummyPing
  1. publicclassMicroRibbonConfig{@BeanpublicIPingmicroIPing(){returnnewDummyPing();}}@RibbonClient(name ="micro-service", configuration =MicroRibbonConfig.class)publicclassRibbonClientConfig{}

Ribbon IPing的作用是保证负载均衡器只选择可用的服务节点,提高系统的可靠性和性能。Ribbon IPing与Eureka结合使用时,可以实现自动化的服务发现和健康检查。

用时间换空间

在Ribbon这里,时间和空间经常要被换来换去,时间代表着接口响应时间(RT,Response Time),空间表示服务器的可用连接数。

在Ribbon里有两个和时间与空间密切相关的负载均衡策略,

  1. BestAvailableRule

(简称BA)和

  1. WeightedResponseTimeRule

。他们都会选择压力较小的服务节点,但这两个策略的方向不同。BA会根据服务节点过去一段时间的请求数,选择并发量最小的机器(选择空间);WRT则是根据响应时间的统计结果,选择响应时间最快的服务(选择时间)。

  • 连接数敏感模型: 对响应时间较短,或RT和业务复杂度是非线性相关关系的接口,采用基于可用连接数的负载均衡策略更加合适。
  • RT敏感模型: 对重量级接口,尤其是根据参数不同会导致系统资源使用率浮动较大的接口(RT与业务复杂度线性相关),建议采用基于响应时间的负载均衡策略。

总结一下就是轻量级接口选空间(

  1. BestAvailableRule

)、重量级接口选时间(

  1. WeightedResponseTimeRule

Ribbon IPing机制源码探秘

IPing接口的定义如下:

  1. publicinterfaceIPing{publicbooleanisAlive(Server server);}

看一下它的几个实现类:

  1. publicclassDummyPingextendsAbstractLoadBalancerPing{publicDummyPing(){}publicbooleanisAlive(Server server){returntrue;}@OverridepublicvoidinitWithNiwsConfig(IClientConfig clientConfig){}}

什么都没发生,直接返回true

  1. publicclassNoOpPingimplementsIPing{@OverridepublicbooleanisAlive(Server server){returntrue;}}

也是直接返回true


  1. PingUrl

的内容比较丰富,关注一下

  1. isAlive

方法:

  1. publicbooleanisAlive(Server server){String urlStr ="";if(this.isSecure){
  2. urlStr ="https://";}else{
  3. urlStr ="http://";}
  4. urlStr = urlStr + server.getId();
  5. urlStr = urlStr +this.getPingAppendString();boolean isAlive =false;HttpClient httpClient =newDefaultHttpClient();HttpUriRequest getRequest =newHttpGet(urlStr);String content =null;try{HttpResponse response = httpClient.execute(getRequest);
  6. content =EntityUtils.toString(response.getEntity());
  7. isAlive = response.getStatusLine().getStatusCode()==200;if(this.getExpectedContent()!=null){
  8. LOGGER.debug("content:"+ content);if(content ==null){
  9. isAlive =false;}elseif(content.equals(this.getExpectedContent())){
  10. isAlive =true;}else{
  11. isAlive =false;}}}catch(IOException var11){
  12. var11.printStackTrace();}finally{
  13. getRequest.abort();}return isAlive;}

如果是安全协议则使用https,不是安全的则使用http,拼接的时候先加上一个

  1. server.getId()

,再加上一个

  1. this.getPingAppendString()
  1. HttpClient httpClient =newDefaultHttpClient();HttpUriRequest getRequest =newHttpGet(urlStr);

构造一个http请求来判断是否是up状态

  1. if(this.getExpectedContent()!=null)

如果有返回的期望值,则需要实际返回的数据等于期望值才证明是服务节点是up的


**

  1. NIWSDiscoveryPing

实现类:**

  1. publicbooleanisAlive(Server server){boolean isAlive =true;if(server!=null&& server instanceofDiscoveryEnabledServer){DiscoveryEnabledServer dServer =(DiscoveryEnabledServer)server;InstanceInfo instanceInfo = dServer.getInstanceInfo();if(instanceInfo!=null){InstanceStatus status = instanceInfo.getStatus();if(status!=null){
  2. isAlive = status.equals(InstanceStatus.UP);}}}return isAlive;}

只有

  1. server

的类型是

  1. DiscoveryEnabledServer

才将其转换成自己需要的类型,然后获得

  1. instanceInfo

这里

  1. InstanceStatus

是依靠

  1. eureka

的服务发现从服务注册中心拉取到的,服务发现并不能即使反映所有服务器的状态变化,因为是客户端发起的,所以有延迟。


本文转载自: https://blog.csdn.net/HNU_Csee_wjw/article/details/124400064
版权归原作者 小王曾是少年 所有, 如有侵权,请联系我们删除。

“Ribbon IPing机制源码探秘”的评论:

还没有评论