服务框架之注册中心,你不知道的内幕
介绍
前一篇服务框架技术栈粗略分析了服务框架需要的各个核心模块,首先提到的就是注册中心,注册中心实现了服务注册和发现的功能,在服务框架中也发挥着重要的作用。今天主要围绕注册中心实现的话题展开。
原理
注册中心作为服务框架核心模块,它是服务框架唯一核心链路上的一个集中点,所以它的好坏也影响着整个服务框架的可用性以及稳定性。
从下面的架构图中,可以看出注册中心要实现的功能就是服务的注册、反注册,服务发现(订阅)、通知,这四个功能。
接下来我们详细解读下这四个功能:
服务注册 register:注册就是将服务的信息注册到注册中心,这里的信息主要是服务的 name、address、weight 信息。name 是服务的名字,address 是服务提供方的地址信息,包含 ip 和 port 信息,weight 是服务节点的权重信息,用来调节流量的,一般配合负载均衡模块一起使用。
服务反注册 unregister:反注册说的是服务提供方机器下线、进程退出的的时候,能够提前将注册中心的相关节点信息删除或者通过相关状态标识出来,表明该服务节点已经不提供服务,这样调用方 Invoker 在发现服务的时候就可以排除掉这个节点,不会将请求发过来。
服务订阅 subscribe:订阅说的是服务调用方,在调用前需要根据订阅服务的 name 从注册中心获取到所有相关服务的注册信息,比如 address、weight。这样在调用前就可以根据 address 信息进行网络连接,然后发起调用,以及根据 weight 来使用负载均衡来调节流量大小。
服务通知 notify:通知说的是相关服务注册和反注册时,注册中心信息变更,能够主动通知到服务订阅方,这样服务订阅方就可以了解到是新增了服务机器节点,还是下线了服务节点,亦或是服务权重变更,这样方便调用方自动控制服务调用流量的流向以及大小。
实现
了解了注册中心的原理之后,我们来谈谈注册中心的实现。要实现一个完美的注册中心其实也不容易,尤其是做到主动的通知功能,这点还是有些工作量的。
所以大部分公司都直接使用了开源的实现,比如 Dubbo 体系的使用 Zookeeper、ETCD 的居多,SpringCloud 体系的使用 Eureka 的居多。
这里更关注的是注册中心通用问题的思考,所以就拿 Zookeeper 来展开,其他的类似实现也会遇到同样的问题。
Zookeeper
Zookeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
Zookeeper 功能较多,能够配置维护、域名服务、分布式同步、组服务等,也有很多服务框架使用 Zookeeper 来做注册中心。
Zookeeper 用来做服务注册中心,主要是因为它具有节点变更通知功能,只要客户端监听相关服务节点,服务节点的所有变更,都能及时的通知到监听客户端,这样作为调用方只要使用 Zookeeper 的客户端就能实现服务节点的订阅和变更通知功能了,非常方便。另外,Zookeeper 可用性还算是可以的,因为只要半数以上的选举节点存活,整个集群就是可用的。
Zookeeper监听通知
注册方式
关于 Zookeeper 的基本知识这里就不做介绍了,这里重点说下当前开源服务框架在注册节点时的两种方式:临时节点和持久节点。
a、临时节点,当客户端与 Zookeeper 集群之间的连接或者 session 断掉时会被集群自动删除。开源 Dubbo 框架,使用的就是临时节点。
临时节点的优势是当服务节点下线或者服务节点不可用,Zookeeper 集群会自动将节点地址信息从注册中心删除。这样保证了注册中心不会残留脏数据。缺点是当存在网络抖动,会导致服务节点自动被移除,导致调用方找不到可用的服务节点信息。
b、持久节点,它与临时节点不同,不会因为连接断开或者服务节点不可用,就会自动从注册中心删除服务节点信息,除非主动调用 API 删除。
优点是解决了临时节点的因网络抖动导致删除的问题;缺点是需要框架考虑从注册中心摘除下线的或者不可用服务节点的信息。
当前大多开源实现使用的是 shutdownHook 来完成,当服务进程推出时,从注册中心删除相关的服务节点信息的工作。了解 shutdownHook 应该知道,依赖 shutdownHook 是不靠谱的。如果进程被 Kill -9,或者进程异常退出等都不会触发shutdownHook的执行,也就是说会导致服务注册信息残留在注册中心。所以还需要其他方式来保证注册中心能够将不可用的或者下线的服务节点信息从注册中心摘除。
为了解决服务节点摘除问题,需要引入第三方探测节点,来探测当前服务节点是否可用,如果不可用可以直接修改注册中心服务节点状态信息,或者直接删除服务节点的注册中心,另外在服务节点重新可用时,还需要重新将服务节点状态信息更新,或者重新写入服务节点信息。
第三方探测
平滑发布
不管是临时节点或者是持久节点,都很难保证发布过程中流量的平滑,因为都存在滞后性,比如说当服务提供方机器需要发布时,这时如果直接发布,重启了服务提供方的服务节点,重启时注册中心服务节点信息状态会变成不可用或者直接删除了,服务调用方会收到注册中心推送的信息,这时候才禁止流量到刚发布的那台机器,其实已经晚了,已经有些请求不能正常处理了。
所以需要提前从注册中心做状态变更或者删除服务提供方节点信息,而将此过程直接加入到发布流程是最合理的,也就是发布时,优先从注册中心摘除服务节点或者变更服务节点状态信息,目的是提前告诉服务调用方,暂时先不要将流量发往该台机器。达到发布过程中流量平滑的目的。
Zookeeper总结
当然,用 Zookeeper 来实现注册中心可能会遇到一些坑,这里我想说的任何一个系统的使用都是有限度的,超过了承载的能力自然会出问题,所以也不用过度的放大它的问题。后面会有文章专门说下 Zookeeper 的坑。
总结
看完这篇文章,是否对注册中心以及服务框架的实现逻辑的理解又加深了呢?后续会继续对服务框架中设计到的技术栈进行展开剖析,希望对你有帮助。
原文链接:https://www.jianshu.com/p/6259ac6085a5