【问题标题】:Data consistency across multiple microservices, which duplicate data跨多个重复数据的微服务的数据一致性
【发布时间】:2019-03-26 11:21:13
【问题描述】:

我目前正在尝试进入微服务架构,但遇到了数据一致性问题。我读过,在多个微服务之间复制数据是个好主意,因为它使每个服务更加独立。

但是,我不知道在以下情况下该怎么做才能提供一致性:

  1. 我有一个具有 RegisterCustomer 方法的客户服务。
  2. 当我注册客户时,我想通过 RabbitMQ 发送一条消息,以便其他服务可以获取此信息并存储在其 DB 中。

我的代码如下所示:

             ...
            _dbContext.Add(customer);
            CustomerRegistered e = Mapper.Map<CustomerRegistered>(customer);
            await _messagePublisher.PublishMessageAsync(e.MessageType, e, "");
            //!!app crashes
            _dbContext.SaveChanges();
            ...

所以我想知道,当应用程序发送消息但无法自行保存数据时,我该如何处理这种情况?当然,我可以交换 DbContextSavePublishMessage 方法,但问题仍然存在。我的数据存储方法有问题吗?

【问题讨论】:

    标签: database transactions microservices data-consistency


    【解决方案1】:

    是的。您正在做双重持久性 - 数据库中的持久性和持久队列。如果一个成功而另一个失败,你总是有麻烦。有几种方法可以解决这个问题:

    1. 保留在 DB 中,然后执行更改数据捕获 (CDC),以便使用来自 DB 预写日志 (WAL) 的数据使用实时流在第二个服务 DB 中创建物化视图

    2. 坚持持久队列和缓存。使用实时流将数据持久保存在这两个服务中。如果数据在缓存中可用,则从缓存中读取数据,否则从数据库中读取。这将允许写入后读取。即使在最坏的情况下写入缓存失败,数据也会在几秒钟内通过流式传输到数据库中

    【讨论】:

      【解决方案2】:

      NServiceBus 在许多情况下与 RMQ 相比确实支持持久 distributed transaction。如果您可以使用 NServiceBus 而不是 RMQ,那么您可以考虑使用该功能来确保在发生故障时将两个上下文一起保存或回滚。

      【讨论】:

        【解决方案3】:

        我认为您正在寻找的解决方案是outbox pattern, 在与您的业务数据相同的数据库中有一个与事件相关的数据库表, 这允许它们在同一个数据库事务中提交, 然后后台工作循环将事件推送到 mq

        【讨论】:

          猜你喜欢
          • 2015-09-15
          • 2019-11-19
          • 2022-10-12
          • 2017-10-19
          • 2017-11-30
          • 2019-04-10
          • 2022-10-16
          • 2015-09-03
          相关资源
          最近更新 更多