热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解SpringCloud负载均衡重要组件Ribbon中重要类的用法

本篇文章主要介绍了详解SpringCloud负载均衡重要组件Ribbon中重要类的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡,而不必在项目里过多地编写实现负载均衡的代码。

比如,在某个包含Eureka和Ribbon的集群中,某个服务(可以理解成一个jar包)被部署在多台服务器上,当多个服务使用者同时调用该服务时,这些并发的请求能被用一种合理的策略转发到各台服务器上。

事实上,在使用Spring Cloud的其它各种组件时,我们都能看到Ribbon的痕迹,比如Eureka能和Ribbon整合,而在后文里将提到的提供网关功能Zuul组件在转发请求时,也可以整合Ribbon从而达到负载均衡的效果。

从代码层面来看,Ribbon有如下三个比较重要的接口。

第一,ILoadBalancer,这也叫负载均衡器,通过它,我们能在项目里根据特定的规则合理地转发请求,常见的实现类有BaseLoadBalancer。

第二,IRule,这个接口有多个实现类,比如RandomRule和RoundRobinRule,这些实现类具体地定义了诸如“随机“和”轮询“等的负载均衡策略,我们还能重写该接口里的方法来自定义负载均衡的策略。

在BaseLoadBalancer类里,我们能通过IRule的实现类设置负载均衡的策略,这样该负载均衡器就能据此合理地转发请求。

第三,IPing接口,通过该接口,我们能获取到当前哪些服务器是可用的,我们也能通过重写该接口里的方法来自定义判断服务器是否可用的规则。在BaseLoadBalancer类里,我们同样能通过IPing的实现类设置判断服务器是否可用的策略。   

1 ILoadBalancer:负载均衡器接口

在Ribbon里,我们还可以通过ILOadBalancer这个接口以基于特定的负载均衡策略来选择服务器。

通过下面的ILoadBalancerDemo.java,我们来看下这个接口的基本用法。这个类是放在4.2部分创建的RabbionBasicDemo项目里,代码如下。  

//省略必要的package和import代码
  public class ILoadBalancerDemo {
    public static void main(String[] args){
      //创建ILoadBalancer的对象 
      ILoadBalancer loadBalancer = new BaseLoadBalancer();
      //定义一个服务器列表
       List myServers = new ArrayList();
      //创建两个Server对象
      Server s1 = new Server("ekserver1",8080);
      Server s2 = new Server("ekserver2",8080);
      //两个server对象放入List类型的myServers对象里  
      myServers.add(s1);
      myServers.add(s2);
      //把myServers放入负载均衡器
      loadBalancer.addServers(myServers);
      //在for循环里发起10次调用
      for(int i=0;i<10;i++){
      //用基于默认的负载均衡规则获得Server类型的对象
        Server s = loadBalancer.chooseServer("default");
      //输出IP地址和端口号
        System.out.println(s.getHost() + ":" + s.getPort());
      }    
   }
  }

在第5行里,我们创建了BaseLoadBalancer类型的loadBalancer对象,而BaseLoadBalancer是负载均衡器ILoadBalancer接口的实现类。

在第6到第13行里,我们创建了两个Server类型的对象,并把它们放入了myServers里,在第15行里,我们把List类型的myServers对象放入了负载均衡器里。

在第17到22行的for循环里,我们通过负载均衡器模拟了10次选择服务器的动作,具体而言,是在第19行里,通过loadBalancer的chooseServer方法以默认的负载均衡规则选择服务器,在第21行里,我们是用“打印”这个动作来模拟实际的“使用Server对象处理请求”的动作。

上述代码的运行结果如下所示,其中我们能看到,loadBalancer这个负载均衡器把10次请求均摊到了2台服务器上,从中确实能看到 “负载均衡”的效果。

第二,IRule,这个接口有多个实现类,比如RandomRule和RoundRobinRule,这些实现类具体地定义了诸如“随机“和”轮询“等的负载均衡策略,我们还能重写该接口里的方法来自定义负载均衡的策略。

在BaseLoadBalancer类里,我们能通过IRule的实现类设置负载均衡的策略,这样该负载均衡器就能据此合理地转发请求。

第三,IPing接口,通过该接口,我们能获取到当前哪些服务器是可用的,我们也能通过重写该接口里的方法来自定义判断服务器是否可用的规则。在BaseLoadBalancer类里,我们同样能通过IPing的实现类设置判断服务器是否可用的策略。 

ekserver2:8080
  ekserver1:8080
  ekserver2:8080
  ekserver1:8080
  ekserver2:8080
  ekserver1:8080
  ekserver2:8080
  ekserver1:8080
  ekserver2:8080
 ekserver1:8080

2 IRule:定义负载均衡规则的接口

在Ribbon里,我们可以通过定义IRule接口的实现类来给负载均衡器设置相应的规则。在下表里,我们能看到IRule接口的一些常用的实现类。

实现类的名字

负载均衡的规则

RandomRule

采用随机选择的策略

RoundRobinRule

采用轮询策略

RetryRule

采用该策略时,会包含重试动作

AvailabilityFilterRule

会过滤些多次连接失败和请求并发数过高的服务器

WeightedResponseTimeRule

根据平均响应时间为每个服务器设置一个权重,根据该权重值优先选择平均响应时间较小的服务器

ZoneAvoidanceRule

优先把请求分配到和该请求具有相同区域(Zone)的服务器上

在下面的IRuleDemo.java的程序里,我们来看下IRule的基本用法。

 //省略必要的package和import代码
  public class IRuleDemo {
    public static void main(String[] args){
    //请注意这是用到的是BaseLoadBalancer,而不是ILoadBalancer接口
    BaseLoadBalancer loadBalancer = new BaseLoadBalancer();
      //声明基于轮询的负载均衡策略
      IRule rule = new RoundRobinRule();
    //在负载均衡器里设置策略 
      loadBalancer.setRule(rule);
      //如下定义3个Server,并把它们放入List类型的集合中
      List myServers = new ArrayList();
      Server s1 = new Server("ekserver1",8080);
      Server s2 = new Server("ekserver2",8080);
      Server s3 = new Server("ekserver3",8080);
      myServers.add(s1);
      myServers.add(s2);
      myServers.add(s3);
      //在负载均衡器里设置服务器的List
      loadBalancer.addServers(myServers);
      //输出负载均衡的结果
      for(int i=0;i<10;i++){
        Server s = loadBalancer.chooseServer(null);
        System.out.println(s.getHost() + ":" + s.getPort());  
     }    
    }
  }

这段代码和上文里的ILoadBalancerDemo.java很相似,但有如下的差别点。

1 在第5行里,我们是通过BaseLoadBalancer这个类而不是接口来定义负载均衡器,原因是该类包含setRule方法。

2 在第7行定义了一个基于轮询规则的rule对象,并在第9行里把它设置进负载均衡器。

3 在第19行里,我们是把包含3个Server的List对象放入负载均衡器,而不是之前的两个。由于这里存粹是为了演示效果,所以我们就放入一个根本不存在的“ekserver3”服务器。

运行该程序后,我们可以看到有10次输出,而且确实是按“轮询”的规则有顺序地输出3个服务器的名字。如果我们把第7行的代码改成如下,那么就会看到 “随机”地输出服务器名。

IRule rule = new RandomRule();  

3  IPing:判断服务器是否可用的接口

在项目里,我们一般会让ILoadBalancer接口自动地判断服务器是否可用(这些业务都封装在Ribbon的底层代码里),此外,我们还可以用Ribbon组件里的IPing接口来实现这个功能。

在下面的IRuleDemo.java代码里,我们将演示IPing接口的一般用法。   

//省略必要的package和import代码
  class MyPing implements IPing {
    public boolean isAlive(Server server) {
      //如果服务器名是ekserver2,则返回false
      if (server.getHost().equals("ekserver2")) {
        return false;
      }
      return true;
    }
  }

第2行定义的MyPing类实现了IPing接口,并在第3行重写了其中的isAlive方法。

在这个方法里,我们根据服务器名来判断,具体而言,如果名字是ekserver2,则返回false,表示该服务器不可用,否则返回true,表示当前服务器可用。    

public class IRuleDemo {
    public static void main(String[] args) {
      BaseLoadBalancer loadBalancer = new BaseLoadBalancer();
      //定义IPing类型的myPing对象
      IPing myPing = new MyPing(); 
      //在负载均衡器里使用myPing对象
      loadBalancer.setPing(myPing);
      //同样是创建三个Server对象并放入负载均衡器
      List myServers = new ArrayList();
      Server s1 = new Server("ekserver1", 8080);
      Server s2 = new Server("ekserver2", 8080);
      Server s3 = new Server("ekserver3", 8080);
      myServers.add(s1);
      myServers.add(s2);
      myServers.add(s3);
      loadBalancer.addServers(myServers);
      //通过for循环多次请求服务器 
      for (int i = 0; i <10; i++) {
        Server s = loadBalancer.chooseServer(null);
        System.out.println(s.getHost() + ":" + s.getPort());
      }
    }
  }

在第12行的main函数里,我们在第15行创建了IPing类型的myPing对象,并在第17行把这个对象放入了负载均衡器。通过第18到第26行的代码,我们创建了三个服务器,并把它们也放入负载均衡器。

在第28行的for循环里,我们依然是请求并输出服务器名。由于这里的负载均衡器loadBalancer中包含了一个IPing类型的对象,所以在根据策略得到服务器后,会根据myPing里的isActive方法来判断该服务器是否可用。

由于在这个方法里,我们定义了ekServer2这台服务器不可用,所以负载均衡器loadBalancer对象始终不会把请求发送到该服务器上,也就是说,在输出结果中,我们不会看到“ekserver2:8080”的输出。

从中我们能看到IPing接口的一般用法,我们可以通过重写其中的isAlive方法来定义“判断服务器是否可用“的逻辑,在实际项目里,判断的依据无非是”服务器响应是否时间过长“或”发往该服务器的请求数是否过多“,而这些判断方法都封装在IRule接口以及它的实现类里,所以在一般的场景中我们用到IPing接口。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • php网站设计实验报告,php网站开发实训报告
    本文目录一览:1、php动态网站设计的关键技术有哪些软件,及搭建步骤需要哪些页面,分别完成 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 护墙_搭建LVS负载均衡NAT和DR模式
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了搭建LVS负载均衡NAT和DR模式相关的知识,希望对你有一定的参考价值。 ... [详细]
  • [翻译]微服务设计模式5. 服务发现服务端服务发现
    服务之间需要互相调用,在单体架构中,服务之间的互相调用直接通过编程语言层面的方法调用就搞定了。在传统的分布式应用的部署中,服务地 ... [详细]
  • 在单位的一台4cpu的服务器上部署了esxserver,挂载了6个虚拟机,目前运行正常。在安装部署过程中,得到了cnvz.net论坛精华区 ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • 抖音服务器带宽有多大,才能供上亿人同时刷?
    最近看到一个有意思的提问:抖音服务器带宽有多大,为什么能够供那么多人同时刷?今天来给大家科普一下。 ... [详细]
  • LVS-DR直接路由实现负载均衡示例
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • pm2常用的命令用法介绍pm2是一个带有负载均衡功能的Node应用的进程管理器.当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, ... [详细]
  • 域名解析系统DNS
    文章目录前言一、域名系统概述二、因特网的域名结构三、域名服务器1.根域名服务器2.顶级域名服务器(TLD,top-leveldomain)3.权威(Authoritative)域名 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
author-avatar
wgol992015
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有