热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RPC的负载均衡策略

抽空自己写了个简易版的rpc框架,想了下怎么搞负载均衡,最简单的方式就是搞个配置文件放置服务地址,直接读配置文件,转而想到配置文件可以放zk,相当于用zk来做配置中心或者服务发现。优秀的du

抽空自己写了个简易版的rpc框架,想了下怎么搞负载均衡, 最简单的方式就是搞个配置文件放置服务地址,直接读配置文件,转而想到配置文件可以放zk,相当于用zk来做配置中心或者服务发现。 优秀的dubbo项目就可以这么做,马上参考了下谷歌的grpc,发现了一篇谷歌很棒的文章,拜读了下(也借用了谷歌这篇文章的图片),很不错,想写一些我自己的见解。

rpc通信本身并不复杂,只要定好协议怎么处理问题不大,但是负载均衡的策略是值得推敲的。

一般情况下,负载均衡的策略有以下两种

1. 代理服务

客户端并不知道服务端的存在,它所有的请求都打到代理服务,由代理服务去分发到服务端,并且实现公平的负载算法。 客户机可能不可信,这种情况通过用户面向用户的服务,类似于我们的nginx将请求分发到后端机器。

缺点: 客户端不知道后端的存在,且客户端不可信,延迟会更高且代理服务会影响服务本身的吞吐量

优点: 在中间层做监控等拦截操作特别棒。

如图: 

2. 客户端负载均衡

客户端知道有多个后端服务,由客户端去选择服务端,并且客户端可以从后端服务器中自己总结出一份负载的信息,实现负载均衡算法。 这种方式最简单的实现就是我上面说的直接搞个配置文件,调用的时候随机或者轮询服务端即可。

如图: 

优点:

高性能,因为消除了第三方的交互

缺点:

客户端会很复杂,因为客户端要跟踪服务器负载和健康状况,客户端实现负载均衡算法。多语言的实现和维护负担也很麻烦,且客户端需要被信任,得是靠谱的客户端。

以上是介绍了两种负载均衡的方案,下面要说的就是使用代理方式负载均衡的几种详细的方案

代理方式的负载均衡有很多种

代理负载平衡可以是 L3/L4(传输级别) 或 L7(应用程序级别)

在 L3/L4 中,服务器终止TCP连接并打开另一个连接到所选的后端。

L7 只是在客户端连接到服务端端连接之间搞一个应用来做中间人。

L3/L4 级别的负载均衡按设计只做很少的处理,与L7级别的负载均衡相比的延迟会更少,而且更便宜,因为它消耗更少的资源。

在L7(应用程序级)负载平衡中,负载均衡服务终止并解析协议。负载均衡服务可以检查每个请求并根据请求内容分配后端。这就意味监控拦截等操作可以非常方便快捷的做在这里。

L3/L4 vs L7

正确的打开方式有一下几种

  1. 这些连接之间的RPC负载变化很大: 建议使用L7.
  2. 存储或计算相关性很重要 :建议使用L7,并使用COOKIE或类似的路由请求来纠正服务端.
  3. 设备资源少(缺钱): 建议使用 L3/L4.
  4. 对延迟要求很严格(就是要快): L3/L4.

下面要说的就是客户端实现负载均衡方式的详细方案:

  public class Test
  
  {
  
  public class InnerClass
  
  {
  
  public int getSum(int x,int y)
  
  {
  
  return x+y;
  
  }
  
  }
  
  public static void main(String[] args)
  
  {
  
  Test.InnerClass testInner =new Test().new InnerClass();
  
  int i = testInner.getSum(2/3);
  
  System.out.println(i); //输出5
  
  }
  
  }
  
  实例内部类
  
  实例内部类是指没有用 static 修饰的内部类
  
  public class Outer
  
  {
  
  class Inner
  
  {
  
  //实例内部类
  
  }
  
  }
  
  在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例,如果有多层嵌套,则内部类可以访问所有外部类的成员
  
  public class Outer
  
  {
  
  class Inner{}
  
  Inner i=new Inner(); //类内部不需要创建外部类实例
  
  public void method0()
  
  {
  
  Inner j=new Inner(); //类内部不需要创建外部类实例
  
  }
  
  public static void method1()
  
  {
  
  Inner r=new Outer().new inner(); //静态方法需要创建外部类实例
  
  }
  
  class Inner1
  
  {
  
  Inner k=new Inner(); //不需要创建外部类实例
  
  }
  
  }
  
  class OtherClass
  
  {
  
  Outer.Inner i=new Outer(yongshi123.cn).new Inner(); //其他类使用时需要创建外部类实例
  
  }
  
  静态内部类
  
  静态内部类是指使用 static 修饰的内部类
  
  public class Outer
  
  {
  
  static class Inner
  
  {
  
  //静态内部类
  
  }
  
  }
  
  在创建静态内部类的实例时,不需要创建外部类的实例
  
  public class Outer
  
  {
  
  static class Inner{}
  
  }
  
  class OtherClass
  
  {
  
  Outer.Inner oi=new Outer.Inner();
  
  }
  
  局部内部类
  
  局部内部类是指在一个方法中定义的内部类
  
  public class Test
  
  {
  
  public void method()
  
  {
  
  class Inner
  
  {
  
  //局部内部类
  
  }
  
  }
  
  }
  
  局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰,局部内部类只在当前方法中有效,局部内部类中可以访问外部类的所有成员
  
  public class Test
  
  {
  
  Inner i=new Inner(www.hnxinhe.cn); //编译出错
  
  Test.Inner ti=new Test.Inner(); //编译出错
  
  Test.Inner ti2=new Test().new Inner(); //编译出错
  
  public void method()
  
  {
  
  class Inner{}
  
  Inner i=new Inner();
  
  }
  
  }
  
  匿名类
  
  匿名类是指没有类名的内部类,必须在创建时使用 new 语句来声明类
  
  new<类或接口>()
  
  {
  
  //类的主体
  
  };
  
  这种形式的 new 语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。使用匿名类可使代码更加简洁、紧凑,模块化程度更高
  
  匿名类有两种实现方式:
  
  继承一个类,重写其方法。
  
  实现一个接口(可以是多个),实现其方法。
  
  public class Out
  
  {
  
  void show()
  
  {
  
  System.out.println("调用 Out 类的 show() 方法");
  
  }
  
  }
  
  public class TestAnonymousInterClass
  
  {
  
  //在这个方法中构造一个匿名内部类
  
  private void show(www.xgjrfwsc.cn)
  
  {
  
  Out anOnyInter=new Out()
  
  {
  
  //获取匿名内部类的实例
  
  void show()
  
  {
  
  System.out.println("调用匿名类中的 show() 方法");
  
  }
  
  };
  
  anonyInter.show();
  
  }
  
  public static void main(String[] args)
  
  {
  
  TestAnonymousInterClass test=new TestAnonymousInterClass();
  
  test.show();
  
  }

1. 笨重的客户端

这就意味着客户端中实现负载平衡策略,客户端负责跟踪可用的服务器以及用于选择服务器的算法。 客户端通常集成与其他基础设施(如服务发现、名称解析、配额管理等)通信的库,这就很复杂庞大了。

2. Lookaside 负载均衡 (旁观?)

旁观式负载平衡也称为外部负载平衡,使用后备负载平衡,负载平衡的各种功能智能的在一个单独的特殊的负载均衡服务中实现。客户端只需要查询这个旁观式的负载均衡服务, 这个服务就能给你最佳服务器的信息,然后你拿这个数据去请求那个服务端。 就像我一开说的比如把服务端的信息注册到zk,由zk去做负载均衡的事情,客户端只需要去zk取服务端数据,拿到了服务端地址后,直接向服务端请求。

如图: 

以上说了这么多,到底服务间的负载均衡应该用哪个,总结以下几点:

  1. 客户端和服务器之间非常高的流量,且客户端是可信的,建议使用‘笨重’的客户端 或者 Lookaside 负载均衡

  2. 传统设置——许多客户端连接到代理背后的大量服务,需要服务端和客户端之间有一个桥梁,建议使用代理式的负载均衡

  3. 微服务- N个客户端,数据中心有M个服务端,非常高的性能要求(低延迟,高流量),客户端可以不受信任,建议使用 Lookaside 负载均衡

 

推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
author-avatar
幸福的FRN
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有