本地消息表是一种在分布式系统中,用于确保数据一致性的解决方案。其实本质上是一张状态表。

核心思想

它的核心思想是利用数据库事务来保证业务操作和发送消息这两个步骤的原子性。简单来说,就是把业务数据的变更和一条“待发送消息”的记录放在同一个本地数据库事务中。这样一来,这两个操作要么都成功,要么都失败,不会出现业务数据更新了但消息没发出去,或者反过来的情况。

工作流程

  1. 业务操作与消息写入:当你的业务逻辑需要通知其他服务时,它会执行以下操作,并且把这两个操作放在同一个数据库事务中:
    • 更新业务数据。
    • 本地消息表中插入一条新的消息记录,状态通常是“待发送”。
  2. 消息发送:有一个独立的后台任务(例如定时任务或常驻服务)会不断扫描本地消息表,查找状态为“待发送”的消息。
  3. 消息消费:后台任务将这些消息发送到消息队列(如 Kafka、RabbitMQMQ)中。发送成功后,它会更新本地消息表中该消息的状态为“已发送”。
  4. 消费方处理:其他服务从消息队列中消费到这条消息,并执行相应的业务逻辑。

本地消息表解决了什么问题?

本地消息表主要解决了分布式事务最终一致性的问题。在微服务架构中,当一个服务需要通知另一个服务进行操作时,如果直接调用,可能因为网络问题或对方服务宕机而失败。如果使用消息队列,又可能因为业务操作成功但发送消息失败,导致数据不一致。本地消息表利用本地事务的可靠性,完美地解决了这个问题,确保了业务操作和消息通知的最终一致性。

优点和缺点

  • 优点
    • 实现简单:它利用了数据库本身的事务能力,逻辑清晰,易于理解和实现。
    • 可靠性高:确保了业务操作和消息发送的原子性,数据不会丢失。
  • 缺点
    • 资源占用:需要额外的数据库表来存储消息,增加了数据库的读写压力。
    • 实时性弱:消息的发送不是实时的,依赖于后台任务的扫描周期,有一定的延迟。
    • 代码侵入性:业务代码中需要额外加入消息表的插入逻辑。