本课时我将和你一起梳理一下面试中分布式事务的高频考点,做到温故知新。
如何考察分布式事务
数据一致性和分布式事务是互联网分布式系统设计中必须要考虑的,所以对分布式事务的考察是中高级工程师面试必须跨过的一道门槛。
面试官通常会通过一个实际的系统设计题来展开提问,以考察候选人对分布式基础理论的理解、对各种数据一致性模型的掌握,以及对分布式下事务实现的原理、机制和各种实现手段的熟悉程度。
下面我模拟一个实际的面试场景,面试官可能会对你提出以下一连串的问题,你可以检测一下自己在学习中的掌握程度:
- 请说说你对分布式系统 CAP 理论的理解,CAP 分别代表什么含义?
- 为什么分布式系统的一致性和可用性不能同时满足?
- 你是如何理解数据一致性的?数据一致性有哪几种模型?
- 你在做系统设计时,如何选择实现强一致性还是弱一致性?
- 在你的项目里,是如何设计分布式事务,实现最终一致性的?
- 你了解数据库的 binlog 和 redolog 吗?是如何实现一致性的呢?
需要说明的是,面试并不是应试考试,很多问题并没有标准答案,不过这里的问题,很多都可以在“模块二:分布式事务”中找到思路。
分布式事务高频考点
在分布式事务的面试中,主要会围绕分布式理论、一致性算法、分布式事务及其应用来展开提问。下面我进行了简单梳理,这里有一张分布式事务的知识点思维导图,你可以对照这张图片,查漏补缺进行分析。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pZWLeVWQ-1677069949064)(https://s0.lgstatic.com/i/image/M00/4D/49/Ciqc1F9Z42uAP8aiAAGiixfdARo703.png)]
分布式理论部分的主要内容包括 CAP 理论、Base 理你好,欢迎来到第 14 课时,本课时主要讲解如何实现服务注册与发现。
在分布式服务中, 服务注册和发现 是一个特别重要的概念,为什么需要服务注册和发现?常用的服务发现组件有哪些?服务注册和发现对一致性有哪些要求呢?下面我们就来学习服务发现相关的知识。
为什么需要服务注册和发现
分布式系统下微服务架构的一个重要特性就是可以快速上线或下线,从而可以让服务进行水平扩展,以保证服务的可用性。
假设有一个电商会员服务,随着业务发展,服务器负载越来越高,需要新增服务器。如果没有服务注册与发现,就要把新的服务器地址配置到所有依赖会员模块的服务,并相继重启它们,这显然是不合理的。
服务注册与发现就是保证当服务上下线发生变更时,服务消费者和服务提供者能够保持正常通信。
有了服务注册和发现机制,消费者不需要知道具体服务提供者的真实物理地址就可以进行调用,也无须知道具体有多少个服务者可用;而服务提供者只需要注册到注册中心,就可以对外提供服务,在对外服务时不需要知道具体是哪些服务调用了自己。
服务注册和发现原理
服务注册和发现的基本流程如下图所示:

首先,在服务启动时,服务提供者会向注册中心注册服务,暴露自己的地址和端口等,注册中心会更新服务列表。服务消费者启动时会向注册中心请求可用的服务地址,并且在本地缓存一份提供者列表,这样在注册中心宕机时仍然可以正常调用服务。
如果提供者集群发生变更,注册中心会将变更推送给服务消费者,更新可用的服务地址列表。
典型服务发现组件的选型
在目前的微服务解决方案中,有三种典型的服务发现组件,分别是 ZooKeeper、Eureka 和 Nacos。
ZooKeeper
ZooKeeper 主要应用在 Dubbo 的注册中心实现,由于 Dubbo 在国内的流行,Dubbo + ZooKeeper 的典型服务化方案,使得 ZooKeeper 成为注册中心的经典解决方案。
ZooKeeper 是一个树形结构的目录服务,支持变更推送。使用 ZooKeeper 实现服务注册,就是应用了这种目录结构。
服务提供者在启动的时候,会在 ZooKeeper 上注册服务。以 com.dubbo.DemoService 为例,注册服务,其实就是在 ZooKeeper 的 /dubbo/com.dubbo.DemoService/providers 节点下创建一个子节点,并写入自己的 URL 地址,这就代表了 com.dubbo.DemoService 这个服务的一个提供者。
服务消费者在启动的时候,会向 ZooKeeper 注册中心订阅服务列表,就是读取并订阅 ZooKeeper 上 /dubbo/com.dubbo.DemoService/providers 节点下的所有子节点,并解析出所有提供者的 URL 地址来作为该服务地址列表。
Eureka
在 Spring Cloud 中,提供了 Eureka 来实现服务发现功能。Eureka 采用的是 Server 和 Client 的模式进行设计,Eureka Server 扮演了服务注册中心的角色,为 Client 提供服务注册和发现的功能。
Eureka Client 通过客户端注册的方式暴露服务,通过注解等方式嵌入到服务提供者的代码中,当服务启动时,服务发现组件会向注册中心注册自身提供的服务,并周期性地发送心跳来更新服务。

如果连续多次心跳不能够发现服务,那么 Eureka Server 就会将这个服务节点从服务注册表中移除,各个服务之间会通过注册中心的注册信息来实现调用。
Euerka 在 Spring Cloud 中广泛应用,目前社区中集成的是 1.0 版本,在后续的版本更新中,Netflix 宣布 Euerka 2.0 闭源,于是开源社区中也出现了许多新的服务发现组件,比如 Spring Cloud Alibaba Nacos。
Nacos
Nacos 是阿里巴巴推出来的一个开源项目,提供了服务注册和发现功能,使用 Nacos 可以方便地集成 Spring Cloud 框架。如果正在使用 Eureka 或者 Consul,可以通过少量的代码就能迁移到 Nacos 上。
Nacos 的应用和 Eureka 类似,独立于系统架构,需要部署 Nacos Server。除了服务注册和发现之外,Nacos 还提供了配置管理、元数据管理和流量管理等功能,并且提供了一个可视化的控制台管理界面。

关于 Nacos 的更多应用,可以在 Nacos 官网 找到相关的文档。
一致性对比
在讨论分布式系统时,一致性是一个绕不开的话题,在服务发现中也是一样。CP 模型优先保证一致性,可能导致注册中心可用性降低,AP 模型优先保证可用性,可能出现服务错误。
为了保证微服务的高可用,避免单点故障,注册中心一般是通过集群的方式来对外服务,比如 ZooKeeper 集群。
ZooKeeper 核心算法是 Zab,实现的是 CP 一致性,所以 ZooKeeper 作为服务发现解决方案,在使用 ZooKeeper 获取服务列表时,如果 ZooKeeper 正在选主,或者 ZooKeeper 集群中半数以上机器不可用时,那么将无法获得数据。
在 Spring Cloud Eureka 中,各个节点都是平等的,几个节点挂掉不影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。只要有一台 Eureka 还在,就能保证注册服务可用,只不过查到的信息可能不是最新的版本,不保证一致性。
Spring Cloud Nacos 在 1.0.0 版本正式支持 AP 和 CP 两种一致性协议,可以动态切换,感兴趣的同学可以去了解一下。
对于服务注册和发现场景来说,一般认为,可用性比数据一致性更加重要。针对同一个服务,即使注册中心的不同节点保存的服务提供者信息不相同,会出现部分提供者地址不存在等,不会导致严重的服务不可用。对于服务消费者来说,能消费才是最重要的,拿到可能不正确的服务实例信息后尝试消费,也要比因为无法获取实例信息而拒绝服务好。
总结
这一课时主要分析了服务注册和发现的基本流程、几种典型的服务发现组件,以及在不同服务发现组件中,是如何实现一致性的。
你可以结合实际工作思考一下,目前公司里的服务发现是如何实现的,是自研还是使用开源组件,以及为什么选择这种服务注册和发现方式?、各种数据一致性模型的应用等。在工作中应用比较多的是 ZooKeeper,需要了解 ZooKeeper 的原理和实现、应用场景等。
一致性算法部分,希望你能够对经典的数据一致性算法,比如 Paxos 算法等有自己的理解,并不是要做到对算法细节倒背如流,而是要能够通过自己的描述,把算法的整体流程讲清楚。
分布式事务的应用是日常开发中打交道最多的部分,如果你在工作中实践过分布式事务的实现是最好的,若没有,可以去了解一些开源的分布式事务中间件。比如我在专栏中多次介绍过的 Alibaba Seata 等组件,通过学习开源组件设计思路,你也可以对这一部分内容有个整体的把握。
在专栏的第 10、 11 课时我们一起讨论了分布式锁的应用场景和实现细节,你可以回顾一下,使用 Redis 实现分布式锁,需要注意哪些细节呢?不同的实现方式,又存在哪些缺陷呢?
另外,除了专栏的内容,我推荐你结合一些经典的公开课程去学习,以加深印象,建议关注拉勾教育直播课哦,有许多分布式相关的主题分享。

被折叠的 条评论
为什么被折叠?



