博客:liufq.com
注册中心作为分布式系统的基础组件,粗略经历了三个阶段:Zookeeper 的 CP 阶段(优先满足一致性),Eureka、Nacos 的 AP 阶段(优先满足可用性),云原生阶段(服务网格)。
之所以这样演变大概是因为微服务初期服务信息都比较小,CP 模式对可用性的影响不大,大家能忍,而且没有一个专门的注册中心组件(Zookeeper 不是专门做注册中心的),还有很大原因是因为 Dubbo 选择了 Zookeeper。
但注册中心本质是个数据库,存的是服务的节点信息,对一致性的要求并不高,节点上下线导致数据变化时,数据不一致可能会导致调用了一个已经下线的服务,这个影响并不大,重试另一个节点就好了,只要保证最终一致性就可以。于是随着服务节点越来越多,Zookeeper 性能问题开始明显,而且毕竟不是专门做注册中心的组件,在健康检查、扩展性等方面不满足需求,这时自然演变成了 Eureka、Nacos 等 AP 模式的组件。
到了云原生时代,把打包、部署、硬件资源分配等都交给了 Kubernetes 等云基础设施完成,有人就想服务发现、负载均衡也是底层通用能力,能不能把这些从业务服务里抽象出来,放到单独的一层网络基础设施层?于是服务网格出现了,但目前还不是很成熟。
注册中心作为微服务最基本的组件之一,深入理解至少一个组件是很有必要的,理解了一个其他都是大同小异的,也很容易理解。主要的产品有 Zookeeper、Consul、Eureka、Nacos。
Nacos
学习 Nacos 首先推荐看下官方出的《Nacos 架构与原理》,这本书里解答了很多为什么的问题,为什么这么设计、为什么选这个通信组件、为什么要造一个新轮子,为什么有时候比是什么更重要。
然后是官方的文档,最后最好自己再部署搭建使用下,这里主要是看这本书记的一些笔记。
点击展开《Nacos 架构与原理》 - 思维导图
看完这本书需要弄懂的几个核心问题
- 一致性设计、通信设计、寻址设计,为什么这么设计?各种方案优缺点和选择原因?
- 注册中心的一致性、数据存储、负载均衡、健康检查如何实现?
- 配置中心的一致性、数据存储如何实现?
Nacos 架构设计原则
架构设计的核心是围绕分层和模块化设计。
设计原则:
- 极简原则,简单才好用,简单才稳定,简单才易协作。
- 架构一致性,一套架构要能适应开源、内部、商业化(公有云及专有云)3个场景。
- 扩展性,以开源为内核,商业化做基础,充分扩展,方便用户扩展。
- 模块化,将通用部分抽象下沉,提升代码复用和健壮性。
- 长期主义,不是要一个能支撑未来3年的架构,而是要能够支撑10年的架构。
- 开放性,设计和讨论保持社区互动和透明,方便大家协作。
Nacos 一致性方案设计
- 各种一致性方案适应场景,分析 Nacos 选择的原因
- 一致性协议具体实现选型
- 一致性协议下沉到内核,成为通用模块
- 一致性协议和数据存储模块拆分解耦
Nacos 通信通道的设计
- 短连接到长连接的升级过程
- 长连接技术选型考虑
- 长连接和短连接在负载均衡方面的差异与选取
Nacos 寻址机制设计
- 通过 MemberLookup 列表维护动态成员节点信息
- 通过单机寻址、文件寻址、地址服务器寻址等方式把节点 ip、端口信息封装成节点加入 MemberLookup 列表
Zookeeper
Zookeeper 的本质是一个保证分布式环境下数据一致的系统。
用作注册中心,数据就是服务 IP、端口等信息,用作配置中心,数据就是配置项,所以 Zookeeper 并不是专门用来做注册中心的,只是它的特点适合用来做注册中心。
既然是分布式环境,CP 和 AP 必然要选择其一,既然要保证数据一致性,必然涉及到数据存储和同步。
所以 Zookeeper 的关键问题就是选择什么样的一致性算法来存储和同步数据。
一致性选取
Zookeeper 的定位决定了它是优先一致性的,也就是 CP 模式,但为了更好的可用性,只要超过半数写入成功就算成功了,牺牲了一定一致性换来更好的可用性,从这个角度看它并不完全是一个强一致性协议。
一致性实现
Zookeeper 通过 ZAB 协议实现一致性,可以简单理解为类似二阶段提交协议,但是第二阶段只要超过半数就算成功。
Zookeeper 节点分为 Leader 和 Follower,Leader 只能有一个,作用类似二阶段协议里的协调者,负责数据写入(所有写入操作都会转发到 Leader),写入的过程会广播所有 Follower 节点写入数据,过半成功后 Leader 才真正提交本次操作(跟二阶段思想是一样的)。由于写操作保证了数据一致性,读操作可以在任意节点直接返回。
上述就是 ZAB 的广播模式,当 Leader 崩溃或者集群刚启动没有 Leader 时,ZAB 进入恢复模式选择一个 Leader。
Leader 选举
选举通过所有节点参与两轮投票选出。
第一轮所有节点都投自己,把自己的 SID(服务器微医标识)和 ZXID(事务 id)发送给其他所有节点。
收到其他节点投票信息后会比较 SID 和 ZXID,发起第二轮投票,优先认可 ZXID 比自己大的,再认可 SID 比自己大的,否则坚持原有投票。
投票需要所有节点的参会,当为了支持更多的客户端加入了很多 Zookeeper 节点时,节点越多延迟也就越高,为了提高选举性能,可以把部分节点设为 Observer 节点,跟 Follower 类似,只是没有投票权,以此来提高投票性能。
Nacos 和 Zookeeper 有什么区别?
主要区别在于:一致性协议、数据模型和使用场景不一样。
一致性协议
Zookeeper 主要通过 ZAB 协议来保证数据一致性,ZAB 是 ZK 自研的一种强一致性协议,在牺牲可用性的情况下保证了一致性;而 Nacos 默认是 AP 模式,用的是阿里自研的 Distro 协议,是一种最终一致性协议,通过定期检查、补齐数据来保证数据一致,优先可用性。同时支持 CP 模式,使用 Raft 协议保证数据一致性。
数据模型
Zookeeper 是通过它的树形节点来存储数据,同时监听节点数据变化,是持久化数据;
Nacos 注册中心默认是非持久化的数据,通过客户端上报来维持数据。当客户端无法上报时也支持持久化服务,使用 CP 模式更新数据。
Nacos 配置中心默认是数据库持久化。
使用场景
Zookeeper 并不是专门用来做注册中心、配置中心的,只不过它的特性恰好可以用来实现注册中心和配置中心,除此之外还可以用作分布式协调、通知、选举、分布式锁等场景。
而 Nacos 是专门为注册中心、配置中心开发的,场景更专一。