经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
Ribbon 负载均衡机制(自定义负载均衡规则)
来源:cnblogs  作者:沛昕的博客  时间:2018/10/19 9:23:47  对本文有异议

Ribbon 负载均衡机制

 在上一章的 "Ribbon 框架简介及搭建(没有与SpringCloud整合,独立使用)" 中介绍了Ribbon框架及搭建使用,那么在这一章会讲一讲Ribbon的负载均衡的机制,以下的规则 笔者将会以通俗易懂的介绍给大家讲解。

 

Ribbon内置的负载均衡规则

1. RoundRobinRule

  通过简单的轮询服务列表,来选择一个服务器
2. AvailabilityFilteringRule
    对以下两种服务器忽略掉,就不会选择它们了。
        2.2 在默认情况下连接失败3次,这个服务器就会被置为"短路"状态,这个状态将持续30秒。如果再连不上,那么这个状态的持续时间将会持续增加。
        # 连接失败的次数,默认为3次
        niws.loadbalancer.<clientName>.connectionFailureCountThreshold
        # 一个实例可以保持"不可用"状态的最大周期,默认为30秒
        niws.loadbalancer.<clientName>.circuitTripMaxTimeoutSeconds
        # 最高并发数
        <clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit
3. WeightedRsponseTimeRule

  会为每一个服务器赋予一个权重值,服务器响应时间越长,这个服务器的权重值就越少,权重有可能会决定服务器的选择(存在随机)
4. ZoneAvoidanceRule

  以区域,可用的服务器为基础进行服务器的选择,使用Zone对服务器进行分类
5. BastAvailableRule

  忽略那些短路的服务器,并选择并发数较低的服务器
6. RandomRule

  随机选择一个可用的服务器
7. RetryRule

  它是一个含有重试机制的选择逻辑

其他配置
NFLoadBalancerPingClassName:检查服务器是否存活
NFLoadBalanceClassName:指定负载均衡器的实现类,可以使用该配置自定义负载均衡器
NIWSServerListClassName:服务器列表的处理类,用来维护服务器列表的
NISServerListFilterClassName:服务器拦截类

 

这里我就不给大家一一贴配置了,感兴趣的可以到官网的wiki去看:https://github.com/Netflix/ribbon

 


 

首先需要创建一个Ribbon服务器,即使在上一章中写过,但是不免有一些懒懒的小伙伴(偷偷的告诉大家,笔者也是其中之一,恨不得直接复制粘贴(*^_^*))。

1:创建Ribbon服务器(一个单纯的SpringBoot程序)

pom.xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. <version>1.5.7.RELEASE</version>
  6. </dependency>
  7. </dependencies>

为了方便Ribbon客户端测试,在这里建一个实体类:Person.java

  1. public class Person {
  2. private String url;// 处理请求的服务器url
  3. private String message;// 提示信息
  4. public String getUrl() {
  5. return url;
  6. }
  7. public void setUrl(String url) {
  8. this.url = url;
  9. }
  10. public String getMessage() {
  11. return message;
  12. }
  13. public void setMessage(String message) {
  14. this.message = message;
  15. }
  16. }

PersonController.java

  1. @RestController
  2. public class PersonController {
  3. @RequestMapping(value="/getPerson", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
  4. public Person getPerson(HttpServletRequest request){
  5. Person p = new Person();
  6. p.setMessage("请求成功");
  7. p.setUrl(request.getRequestURL().toString());
  8. return p;
  9. }
  10. }

启动类:Application.java(因为要测试负载均衡,所有这里需要启动多个服务,以下配置以手动输入端口号方式启动)

  1. @SpringBootApplication
  2. public class Application {
  3. public static void main(String[] args) {
  4. Scanner scan = new Scanner(System.in);
  5. String port = scan.nextLine();
  6. new SpringApplicationBuilder(Application.class).properties("server.port="+port).run(args);
  7. }
  8. }

本次启动以端口:8080、8081分别启动,稍后我们配置完客户端 统一测试(配置后,将服务启动)

 

2:创建Ribbon客户端

pom.xml 中只需要引入核心及客户端的依赖即可

  1. <dependency>
  2. <groupId>com.netflix.ribbon</groupId>
  3. <artifactId>ribbon-core</artifactId>
  4. <version>2.2.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.netflix.ribbon</groupId>
  8. <artifactId>ribbon-httpclient</artifactId>
  9. <version>2.2.5</version>
  10. </dependency>

上面的配置与上一章的内容完全一样,那么接下来的内容大家就要注意了,也是本次讲解的重点。(本次的事例有轮询 + 自定义负载均衡器 + 访问服务)

 

使用默认的轮询规则


  1. public
    static void main(String[] args) throws Exception {
  2. // 创建负载均衡器对象
  3. ILoadBalancer lb = new BaseLoadBalancer();
  4. // 设置服务器列表
  5. List<Server> servers = new ArrayList<Server>();
  6. servers.add(new Server("localhost", 8080));
  7. servers.add(new Server("localhost", 8081));
  8. // 向负载均衡器中添加服务列表
  9. lb.addServers(servers);
  10. // 默认规则:轮询
  11. for(int i=0; i<10; i++){
  12. Server s = lb.chooseServer(null);
  13. System.out.println(s);
  14. }
  15. }

 

使用自定义负载均衡器

  1. /***
  2. * 自定义负载均衡器,这里需要实现“IRule”接口
  3. * 比如端口为8081的服务器是新买的,不想让它处理太多的任务,那么可以用随机数去控制它的访问量
  4. * @author lpx
  5. *
  6. */
  7. public class MyRule implements IRule{
  8. private ILoadBalancer lb;// 声明负载均衡器接口
  9. @Override
  10. public Server choose(Object key) {
  11. // 获取服务器列表
  12. List<Server> servers = lb.getAllServers();
  13. // 生产随机数
  14. Random r = new Random();
  15. int rand = r.nextInt(10);
  16. if(rand > 7){
  17. return getServerByPort(servers, 8081);
  18. }else{
  19. return getServerByPort(servers, 8080);
  20. }
  21. }
  22. /**
  23. * 根据传入的端口号,返回服务对象
  24. * @param servers
  25. * @param port
  26. * @return
  27. */
  28. private Server getServerByPort(List<Server> servers, int port){
  29. for(Server s : servers){
  30. if(s.getPort() == port){
  31. return s;
  32. }
  33. }
  34. return null;
  35. }
  36. @Override
  37. public void setLoadBalancer(ILoadBalancer lb) {
  38. this.lb = lb;
  39. }
  40. @Override
  41. public ILoadBalancer getLoadBalancer() {
  42. return this.lb;
  43. }
  44. }
  1. public static void main(String[] args) throws Exception {
  2. // 创建负载均衡器
  3. BaseLoadBalancer blb = new BaseLoadBalancer();
  4. // 创建自定义负载均衡器
  5. MyRule myRule = new MyRule();
  6. // 设置负载均衡器
  7. myRule.setLoadBalancer(blb);
  8. // 设置负载均衡器规则
  9. blb.setRule(myRule);
  10. // 设置服务器列表
  11. List<Server> servers = new ArrayList<Server>();
  12. servers.add(new Server("localhost", 8080));
  13. servers.add(new Server("localhost", 8081));
  14. blb.setServersList(servers);
  15. for(int i=0; i<10; i++){
  16. Server s = blb.chooseServer(null);
  17. System.out.println(s);
  18. }
  19. }

 

使用自定义负载均衡器访问服务

  1. public static void main(String[] args) throws Exception {
  2. // 写入服务列表
  3. ConfigurationManager.getConfigInstance().setProperty("my-client.ribbon.listOfServers", "localhost:8080,localhost:8081");
  4. // 配置规则类
  5. ConfigurationManager.getConfigInstance().setProperty("my-client.ribbon.NFLoadBalancerRuleClassName", MyRule.class.getName());
  6. // 输出服务列表
  7. System.out.println("服务列表:" + ConfigurationManager.getConfigInstance().getProperty("my-client.ribbon.listOfServers"));
  8. // 创建客户端
  9. RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
  10. // 创建request对象
  11. HttpRequest request = HttpRequest.newBuilder().uri(new URI("/getPerson")).build();
  12. // 多次访问测试
  13. for (int i = 0; i < 10; i++) {
  14. // 创建response对象
  15. HttpResponse response = client.executeWithLoadBalancer(request);
  16. // 接收请求结果
  17. String json = response.getEntity(String.class);
  18. // 打印结果
  19. System.out.println(json);
  20. }
  21. }

 

 

OK,以上就是本文的全部内容(负载均衡规则的机制 + 自定义负载均衡规则 + 访问服务),如果笔者有写的不对的地方还望大家提出,蟹蟹!!!

 

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号