分布式服务框架上线运行时都是集群组网,这意味着集群中存在某个服务的多实例部署,消费者如何从服务列表中选择某个服务进行调用,这就涉及到服务路由。分布式服务框架要能够满足用户灵活的路由需求。
一.透明化路由
透明化路由:指的是服务消费者,不需要感知服务提供者的位置。就可以进行服务调用。
1.基于服务注册中心的订阅发布
在分布式服务框架中,服务注册中心用于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的方式获取服务提供者的地址信息。
服务消费者和服务提供者通通过注册中心提供的SDK与注册中心建立链路(例如:ZooKeeper采用长连接),服务提供者将需要发布的服务地址信息和属性列表写入到注册中心。服务消费者根据本地引用的接口名等信息,从服务注册中心获取服务提供者列表,缓存到本地。
当注册中心检测到服务提供者列表变更之后,将变更内容主动推送给服务消费者,服务消费者根据变更列表,动态刷新本地缓存的服务提供者地址。
2.消费者缓存服务提供者地址
- 第一次主动获取服务提供者列表之后,进行本地缓存。消费者调用服务提供者时,从本地缓存的服务者路由表中查询地址信息,根据路由策略,进行服务选路。
- 当服务提供者发生变话,注册中心主动将变更内容推送给消费者,由后者动态刷新本地缓存的服务路由表。
好处: - 提升服务调用性能:减少服务查询时间
- 保证系统可靠性:当注册中心全部宕掉后,服务提供者和服务消费者仍然可以通过本地缓存的地址信息进行通信,只是影响新服务的注册和老服务的下线,不影响已经发布和运行的服务。
二.负载均衡
负载均衡策略是服务的重要属性。常用的负载均衡策略:
1.随机
采用随机算法进行负载均衡,通常在对等集群组网中,随机路由算法消息分发还是比较均匀的。缺点主要有两个:
- 在一个截面上碰撞的概率比较高;
- 非对等集群组网中,或者硬件配置差异较大,会导致各节点负载不均匀。
2.轮循
轮循:按公约后的权重设置轮循比例,到达边界之后,继续绕接。缺点主要是存在慢的提供者累积请求的问题。
轮循策略的实现非常简单,其原理就是按照权重,顺序循环遍历服务提供者列表,到达上限之后重新归零,集训顺序循环。
3.服务调用时延
消费者缓存所有服务提供者的服务调用时延,周期性的计算服务调用平均时延,然后计算每个服务提供者服务调用时延与平均时延的差值,根据差值大小动态调整权重,保证服务时延大的服务提供者接受更少的消息,防止消息堆积。
4.一致性哈希
一致性哈希,维基百科中定义:
一致性哈希是一种特殊的哈希算法。再使用一致性哈希算法后,哈希表槽位数(大小)的改变平均只需要对K/n个关键字重新映射,其中K是关键字的数量,n是槽位数量。然而再传统的哈希表中,添加或者删除一个槽位,几乎需要对所有关键字重新映射。
- 普通哈希:
即哈希取模的计算方式则。对访问者IP,通过固定算式计算:hash(IP) % N,(N为服务器的个数)。使得每个IP可以定位到特定的服务器。其中:通过Hash算法(比如MD5算法)能够实现比较随机的分布。
存在问题:由于哈希,强依赖于服务器的个数。当新增或者删除服务器节点时,几乎需要对服务器上的所有数据进行重新迁移。 - 一致性哈希
解决问题:当服务器节点个数发生变化时,需要保证尽量少的数据迁移?即:当增加或者删除节点时,对于大多数的item,保证原来分配到的某个node,现在仍然应该分配到那个node,将数据迁移量降到最低。
思考:由于Hash取模之后得到的是一个 int 型的整值,其最大值是2^31-1。 故可以不对服务器的数量进行取模而是直接对2^32取模。
简单来说,一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1(即哈希值是一个32位无符号整形),整个哈希环如下,从 0 ~ 2^32-1 代表的分别是一个个的节点,这个环也叫哈希环。
- 服务器节点:通过对2^32取模,映射到哈希环上。
- 用户IP:使用上面相同的函数 Hash 计算出哈希值,并确定此数据在环上的位置,从此位置沿环 顺时针行走,遇到的第一台服务器就是其应该定位到的服务器。
由于环上服务器节点分布不均匀,导致其负责的范围不均匀。
解决方法:通过增加“虚拟节点”,让虚拟节点在环上均匀分布。再增加一层虚拟节点到真是物理节点的映射即可。
每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。
5.粘滞连接
粘滞连接用于有状态服务,尽可能让客户端总是向同一服务提供者发起服务调用,除非该提供者宕机,再连接另一台。由于服务通常被强烈建议设计成无状态的,因此该模式很少使用。
三.本地路由优先策略
1.injvm模式
有些业务场景,本地JVM内部也发布了需要消费的服务。从可靠性、性能等角度考虑,优先调用本JVM内部的服务提供者,这种本地优先的路由模式称为injvm模式。相比与远程服务调用,内部调用更加可靠安全,上层用户不需要感知。
2.innative模式
如果物理机或者VM配置比较好,多个应用进程往往会选择合设。服务提供者可能会被部署到同一台机器上。服务路由时,优先选择本机的服务提供者,如果找不到,再重新发起远程服务调用,该模式称为innative模式。
四.路由规则
负载均衡、本地路由优先等路由策略可以满足大部分场景,但是一些场景需要对路由策略设置一些过滤条件。比较常用的是:
- 条件路由规则
- 脚本路由规则。
五.路由策略定制
平台除了提供默认的路由策略之外,在架构上还需要支持业务扩展路由算法,实现业务自定义路由。
六.配置化路由
路由配置策略设计如下:
- 本地配置:包括服务提供者和服务消费者、默认全局配置三种。
- 统一注册管理:无论是服务提供者还是消费者,本地配置的路由策略统一注册到服务注册中心,进行集中化配置管理。
- 动态下发