1

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

但是,我无法弄清楚在以下情况下该怎么做才能提供一致性:

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

我的代码看起来像这样:

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

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

4

3 回答 3

0

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

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

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

于 2019-03-26T17:14:08.973 回答
0

NServiceBus 与 RMQ 相比,在许多场景中确实支持持久的分布式事务。如果您可以使用 NServiceBus 而不是 RMQ,那么您可以考虑使用该功能来确保在发生故障时将两个上下文一起保存或回滚。

于 2019-11-07T12:40:54.563 回答
0

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

于 2021-11-09T09:31:31.153 回答