MST

星途 面试题库

面试题:Node.js微服务异步通信中的分布式事务处理

在Node.js构建的微服务架构中,各微服务通过异步通信交互数据。当涉及到跨多个微服务的业务操作需要保证数据一致性,即需要处理分布式事务时,你会采用何种策略和技术方案?请详细阐述该方案的设计思路、实现步骤以及可能面临的挑战与解决方案。
31.9万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

策略与技术方案

  1. 两阶段提交(2PC)
    • 设计思路:引入一个协调者(Coordinator)角色。第一阶段,协调者向所有参与者发送准备指令,参与者执行事务操作但不提交,然后反馈准备结果。第二阶段,若所有参与者都准备成功,协调者发送提交指令,参与者正式提交事务;若有任何一个参与者准备失败,协调者发送回滚指令,参与者回滚事务。
    • 实现步骤
      • 准备阶段:协调者通过消息队列向各微服务发送准备请求,微服务执行事务逻辑,记录日志,将数据修改设为暂存状态,并向协调者回复准备成功或失败。
      • 提交/回滚阶段:协调者根据准备阶段的反馈,若全部成功则发送提交消息到消息队列,微服务收到后正式提交事务;若有失败则发送回滚消息,微服务回滚事务。
    • 挑战与解决方案
      • 单点故障:协调者故障会导致事务无法继续。解决方案是采用主备协调者,主协调者故障时备协调者接管。
      • 同步阻塞:在两阶段过程中,参与者处于阻塞状态等待指令。可优化为尽量缩短阻塞时间,如采用异步消息确认机制。
  2. 三阶段提交(3PC)
    • 设计思路:在2PC基础上增加一个预提交阶段。第一阶段询问参与者是否可执行事务,参与者回复可执行能力;第二阶段预提交,协调者收到所有可执行回复后发送预提交指令,参与者执行事务但不提交;第三阶段提交,协调者确认所有预提交成功后发送提交指令。
    • 实现步骤
      • 询问阶段:协调者向微服务发送询问消息,微服务检查自身资源等情况,回复是否可执行事务。
      • 预提交阶段:协调者根据询问结果,若都可执行则发送预提交消息,微服务执行事务操作并记录日志,暂不提交,回复预提交结果。
      • 提交阶段:协调者收到所有预提交成功回复后,发送提交消息,微服务正式提交事务。
    • 挑战与解决方案
      • 网络分区:部分节点网络故障时可能导致不一致。解决方案是设置合理超时机制,超时后进行补偿操作。
  3. TCC(Try - Confirm - Cancel)
    • 设计思路:将事务分为三个操作。Try阶段,微服务尝试预留资源;Confirm阶段,确认提交事务,执行真正的业务操作;Cancel阶段,若Try失败或后续需要回滚,释放预留资源。
    • 实现步骤
      • Try阶段:业务发起方调用各微服务的Try接口,微服务检查资源并预留,返回尝试结果。
      • Confirm阶段:若所有Try都成功,发起方调用各微服务的Confirm接口,微服务执行正式业务操作。
      • Cancel阶段:若Try阶段有失败,发起方调用各微服务的Cancel接口,微服务释放预留资源。
    • 挑战与解决方案
      • 幂等性:Confirm和Cancel操作需保证幂等性,防止重复调用导致数据不一致。可通过记录操作日志,每次操作前检查日志实现。
  4. 基于消息队列的最终一致性
    • 设计思路:业务操作时,先记录操作日志到本地数据库,同时发送消息到消息队列。微服务从消息队列消费消息,按顺序执行操作,通过定期对账等机制保证最终数据一致性。
    • 实现步骤
      • 消息生产:业务执行时,在本地数据库记录操作记录,并发送包含操作信息的消息到消息队列。
      • 消息消费:微服务从消息队列拉取消息,根据消息内容执行相应业务逻辑,并更新本地状态。
      • 对账:定期通过数据库记录与微服务状态进行比对,发现不一致进行修复。
    • 挑战与解决方案
      • 消息丢失:消息队列故障可能导致消息丢失。可采用持久化消息队列,同时生产者采用可靠消息投递机制,如发送消息后等待确认,未确认则重试。