I want to fly higher
programming Explorer
posts - 114,comments - 263,trackbacks - 0

服务的路由和负载均衡

公共的业务被拆分出来,形成可共用的服务,最大程度的保证了代码和逻辑的复用,避免重复建设,这种设计也被成为SOA(Service-Oriented Architecture)
SOA架构中,服务消费者通过服务名称,在众多服务中找到要调用的服务的地址列表,成为服务的路由:

而对于负载较高的服务来说,往往对应着由多台服务器组成的集群。在请求到来时,为了将请求均衡地分配到后端服务器,负载均衡程序将从服务对应的地址列表中,通过相应的负载均衡算法和规则,选取一台服务器进行访问,这个过程称为服务的负载均衡:

当服务的规模较小时,可以采用硬编码的方式将服务地址和配置写在代码中,通过编码的方式来解决服务的路由和负载均衡问题,也可以通过传统的硬件负载均衡设备如F5等,或者采用LVS或Nginx等软件解决方案,通过相关配置,来解决服务的路由和负载均衡问题。由于服务的机器数量在可控范围内,因为维护成本能够接受。

当服务越来越多,规模越来越大时,对应的机器数量也越来越庞大。单靠人工来管理和维护服务及地址的配置信息等,已经越来与困难。并且,依赖单一的硬件负载均衡设备或者使用LVS、Nginx等软件解决方案进行路由和负载均衡调度,单点故障的问题也开始凸显,一旦服务路由或者负载均衡服务器宕机,依赖它的所有服务均将失效。

此时,需要一个能够动态注册和获取服务信息的地方,来统一管理服务名称和其对应的服务器列表信息,称之为服务配置中心。服务提供者在启动时,将其提供的服务名称、服务地址注册到服务配置中心,服务消费者通过服务配置中心来获得需要调用的服务的机器列表,通过相应的负载均衡算法,选取其中一台服务器进行调用。当服务器宕机或者下线时,相应的机器需要能够动态的从服务配置中心里面移除,并通知相应的服务消费者,否则服务消费者就有可能因为调用到已经失效的服务而发生错误。在这个过程中,服务消费者只有在第一次调用服务时需要查询服务配置中心,然后将查询到的信息缓存到本地,后面的调用直接使用本地缓存的服务地址列表信息,而不需要重新发起请求到服务配置中心去获取相应的服务地址列表,直到服务的地址列表有变更(机器上线或者下线)。这种无中心化的结构解决了之前负载均衡设备所导致的单点故障问题并且大大减轻了服务配置中心的压力。
基于Zookeper的持久和非持久节点,我们能够近乎实时的感知到后端服务器的状态(上线、下线、宕机)。通过集群间zab协议,使得服务配置信息能够保持一致。而Zookeeper本身容错特性和leader选举机制,能保障我们方便的进行扩容。通过Zookeeper来实现服务动态注册、机器上线与下线的动态感知、扩容方便、容错性好,且无中心化结构能够解决之前使用负载均衡设备所带来的单点故障问题,只有当配置信息更新时才会去Zookeeper上获取最新的服务地址列表,其他时候使用本地缓存即可。

负载均衡算法

服务消费者从服务配置中心获取到服务的地址列表后,需要选择其中一台来发起RPC调用。如何选择,则取决于具体的负载均衡算法,对应于不同的场景,选择负载均衡算法也不尽相同。
  • 轮询法(Round Robin)
    将请求按顺序轮流的分配到后端服务器上,它均衡的对待后端每一台服务器,而不关心服务器实际的连接数和当前的系统负载
  • 随机法
    通过系统随机函数,根据后端服务器列表大小值来随机选取其中一台进行访问。
  • 源地址哈希(Hash)法
    获取客户端访问的IP地址值,通过哈希函数计算得到一个数值,用该数值对服务器列表的大小进行取摩运算,得到的结果便是要访问的服务器的序号。采用哈希发进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会被映射到同一台后端服务器进行访问。
  • 加权轮询法(Weight Round Robin)
    不同的后端服务器可能机器的配置和当前系统的负载并不相同,因为他们的抗压能力也不尽相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请求,而低配置、负载高的机器,则给其分配较低的权重,降低其系统负载。加权轮询能吹该问题并将请求顺序且按照权重分配到后端。
    注意:目前的代码实现是如果某机器A权重配的比较高,则serverlist中该机器A会按照权重被加入多次,即serverlist中有多个A,则按照轮询法则会处理更多请求.
  • 加权随机法(Weight Random) 与加权轮询法类似,加权随机法也根据后端服务器不同的配置和负载情况,配置不同的权重、不同的是,它是按照权重来随机选取服务器的,而非顺序。
  • 最小连接数法(Least Connections) 根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后端服务器的利用效率,将负载合理的分流到每一台机器。

路由和负载均衡的实现

服务配置中心节点树分成三层结构,最上面一层为根节点,用来聚集服务节点,通过它可以查询到所有的服务,而服务名称节点挂载的是服务提供者的服务器地址,服务消费者通过负载均衡算法选择其中一个地址发起远程调用。根节点和服务名称采用的是ZoooKeeper的持久节点,也就是persistent节点,而服务提供者的地址节点则采用非持久节点,即ephemeral节点,一旦服务器宕机或者下线,节点也就随之消失。

Http网关

gateway接收外部各种app的http请求,完成相应的权限与安全校验。当校验通过后,根据传入的服务名称,到服务配置中心找到相应的服务名称节点,并加载对应服务提供者的地址列表,通过前面提到的负载均衡算法,选取机器发起远程调用,将客户端参数传递到后端服务端。服务提供方根据所传入的参数,给出正确的响应,当gateway接收到响应后,再将响应输出给客户端APP.
对于外部的APP来说,它依赖gateway进行服务的路由以及请求的转发,gateway是整个网络的核心节点,一旦gateway失效,所有依赖它的外部app都将无法使用且流量之大。所以考虑到系统流量的监控和容量规划以及gateway集群的可扩展性,以便在流量达到极限之前,能够快速的方便的进行系统扩容。

一组对等的服务器组成网关集群,接收外部APP的http请求,当流量水位达到警戒值时,能够较为方便的增加机器进行扩容。网关的前面有两台负载均衡设备,负载对网关集群进行负载均衡,负载均衡设备之间进行心跳检测,一旦其中一台进行宕机,另一台则变更自己的地址,接管宕机的这台设备的流量。平时两台机器均对外提供服务。

分布式系统基础措施

  • 分布式协作及配置管理系统ZooKeeper
  • 分布式缓存系统
  • 持久化存储
  • 分布式消息系统
  • 搜索引擎
  • CDN系统
  • 负载均衡系统
  • 运维自动化系统
  • 实时计算系统
  • 离线计算系统
  • 分布式文件系统
  • 日志收集系统
  • 监控系统
  • 数据仓库
posted on 2016-07-19 14:58 landon 阅读(1420) 评论(0)  编辑  收藏 所属分类: Book

只有注册用户登录后才能发表评论。


网站导航: