MST

星途 面试题库

面试题:设计一个基于消息队列的无服务器架构分布式事务方案

假设业务场景需要在无服务器架构下通过消息队列实现分布式事务,要求保证数据的一致性和事务的最终完成。请设计一个完整的方案,包括事务发起、消息传递、各参与方处理逻辑以及异常处理机制等,并分析该方案在高并发场景下的优缺点。
27.2万 热度难度
后端开发消息队列

知识考点

AI 面试

面试题答案

一键面试

方案设计

事务发起

  1. 业务逻辑:在事务发起端,应用程序确定需要执行的分布式事务操作。例如,一个电商场景中,下单操作可能涉及创建订单、扣减库存、更新用户积分等多个子事务。
  2. 消息生成:将事务相关信息封装成消息。消息内容包含事务ID、事务类型、各子事务的操作指令及相关数据等。例如,消息格式可以是JSON:
{
    "transactionId": "123456",
    "transactionType": "orderCreate",
    "operations": [
        {
            "operation": "createOrder",
            "data": {
                "orderId": "123456",
                "userId": "user1",
                "productList": [{"productId": "product1", "quantity": 1}]
            }
        },
        {
            "operation": "deductStock",
            "data": {
                "productId": "product1",
                "quantity": 1
            }
        },
        {
            "operation": "updateUserPoints",
            "data": {
                "userId": "user1",
                "points": 10
            }
        }
    ]
}
  1. 消息发送:将消息发送到消息队列。可以使用常见的消息队列如RabbitMQ、Kafka等。在发送消息时,设置消息的持久化属性,确保消息不会因队列服务重启等原因丢失。

消息传递

  1. 消息队列:消息队列接收并存储事务消息。以RabbitMQ为例,消息会被存储在相应的队列中,等待消费者获取。消息队列提供了可靠的消息存储和传递机制,保证消息在传递过程中的可靠性。
  2. 消息分发:消息队列按照一定的策略将消息分发给各个参与方对应的消费者。例如,可以根据事务类型或者参与方标识进行路由分发。

各参与方处理逻辑

  1. 消费者监听:各参与方子系统启动消费者,持续监听消息队列中属于自己的消息。例如,库存服务的消费者监听与库存操作相关的消息。
  2. 事务执行:当消费者接收到消息后,根据消息中的操作指令和数据执行本地事务。例如,库存服务接收到扣减库存的消息后,执行扣减库存的SQL操作:
UPDATE products
SET stock = stock - 1
WHERE product_id = 'product1' AND stock >= 1;
  1. 消息确认:本地事务执行成功后,消费者向消息队列发送确认消息,表明该消息已被成功处理。如果消息队列采用ACK机制,只有收到确认消息后,才会将该消息从队列中删除。如果本地事务执行失败,消费者不发送确认消息,消息队列会根据配置进行重试(如RabbitMQ的死信队列机制可用于处理重试等情况)。

异常处理机制

  1. 本地事务异常:如果某个参与方在执行本地事务时发生异常,如库存不足导致扣减库存失败,该参与方不确认消息,消息队列会根据重试策略进行重试。可以设置重试次数和重试间隔,例如重试3次,每次间隔1秒。
  2. 消息传递异常:如果消息在传递过程中丢失(如网络故障等原因),消息队列的持久化机制可以保证消息不会丢失。若消费者在处理消息过程中崩溃,消息队列同样会进行重试。
  3. 全局事务异常:如果部分子事务成功,部分失败,需要进行补偿操作。例如,订单创建成功但库存扣减失败,需要回滚订单。可以在消息中添加补偿操作指令,当出现全局事务异常时,各参与方按照补偿指令执行反向操作。

高并发场景下的优缺点分析

优点

  1. 可扩展性:无服务器架构天然具备良好的扩展性,消息队列也可以通过集群等方式轻松应对高并发。各参与方可以根据自身负载动态调整资源,如增加或减少消费者实例,以适应高并发流量。
  2. 解耦性:通过消息队列实现分布式事务,各参与方之间解耦,不需要直接相互调用。这使得系统在高并发下更具灵活性,一方的故障或性能问题不会直接影响其他方。
  3. 可靠性:消息队列的持久化和重试机制保证了在高并发场景下数据的一致性和事务的最终完成。即使部分操作失败,通过重试和补偿机制也能确保事务达到最终一致状态。

缺点

  1. 性能开销:消息的创建、发送、接收和处理都存在一定的性能开销。在高并发场景下,这种开销可能会累积,导致整体系统性能下降。例如,消息序列化和反序列化、网络传输等操作都会消耗系统资源。
  2. 一致性延迟:虽然能保证最终一致性,但由于消息处理存在一定的时间差,在高并发场景下,从事务发起至最终所有参与方达成一致状态的时间可能会延长,可能导致部分业务场景下用户体验不佳。
  3. 复杂度增加:引入消息队列和无服务器架构后,系统的运维和调试复杂度增加。在高并发场景下,排查问题变得更加困难,如消息积压、重试策略不当等问题不易快速定位和解决。