【问题标题】:MassTransit: Queing consumption of different messages for related dataMassTransit:排队消费相关数据的不同消息
【发布时间】:2020-11-29 15:30:00
【问题描述】:

设置

我正在使用带有 EFCore 的 ASPNET Core。

我已设置 MassTransit 以帮助在服务之间复制 UsersTokens

每个User有多个Tokens,它们通过Token.UserId外键连接。

问题

创建新的User 时,会发生两件事:

  • User 和新鲜的Token 存储在数据库中
  • UserCreatedTokenCreated 被发送到消息总线模拟

实际上,Token(因为它更小)在User 之前被处理,并且弹出一个错误提示User of given Id defined in Token.UserId doesn't exist in table Users - 这是真的,因为User 是与Token 一起异步创建的。

我找到了一些解决方案,例如删除外键约束或在 Consume 方法中实现延迟 - 这两种方法似乎都是最终会回到我身边的惰性解决方案。

有没有办法将两个事件放在同一个队列中并按顺序执行它们,或者我应该只在UserCreated 中包含初始令牌?

【问题讨论】:

    标签: entity-framework-core masstransit


    【解决方案1】:

    在消息合约设计方面,尤其是在产生事件时...

    事件应该是独立的

    每个事件都应该是特定事件的完整表示。这意味着事件不应该引用其他数据源,不应该包含外键,也不应该需要回调支持服务来响应事件。

    在您的场景中,您可能希望在 TokenCreated 事件中包含足够的用户信息,以便可以根据该事件中的数据添加新用户,或者创建包含两个数据集的第三个事件 - 也许UserTokenCreated。当同时创建新用户和新令牌时,将产生第三个事件。

    另一种选择是使用 saga 来组合这两个事件,但这似乎比您需要的复杂。

    您还可以使用代理的延迟消息功能在未来通过一些延迟重新安排消息的传递,而不是像现在看起来那样使用 Task.Delay() 来简单地阻塞消费者槽。

    【讨论】:

    • 嗯,我正在考虑将令牌信息放入 UserCreated 事件中,但这似乎不可避免地将这些资源绑定在一起 - 但是,就像 CAP 定理和一般的微服务一样 - 我可能不得不采取这种权衡换取更大的利益。
    • 这是一个合理的权衡。老实说,移除 FK 也是如此(反正我几乎从不使用它们)。但是,我会专注于不必在边缘/缓存层进行连接,并且会使用平面模型来避免查询复杂性。
    • 当然。感谢您花时间帮助我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    相关资源
    最近更新 更多