rabbitmq - 消息类型 : how much information should messages contain?

标签 rabbitmq domain-driven-design message-queue integration-patterns

我们目前开始将事件从一个中央应用程序广播到其他可能感兴趣的消费者应用程序,并且我们的团队成员对 有不同的选择。我们应该在我们发布的消息中投入多少 .

总体思路/架构如下:

  • 生产者申请 :
  • 用户与一些可以创建/修改/删除的实体(DDD 意义上的聚合根)进行交互
  • 根据正在发生的事情,引发域事件(例如:EntityXCreated、EntityYDeleted、EntityZTransferred 等......即不仅是 CRUD,而且主要是)
  • 引发的事件被翻译/转换为我们发送到 RabbitMQ Exchange
  • 的消息
  • 兔MQ (我们使用的是 RabbitMQ,但我相信这个问题实际上与技术无关):
  • 我们为每个消费应用程序定义一个队列
  • 绑定(bind)将交换连接到消费者队列(可能带有消息过滤)
  • 使用应用程序
  • 应用程序使用并处理来自其队列的消息

  • 基于 Enterprise Integration Patterns我们正在尝试为我们发布的消息定义规范格式,并且在两种方法之间犹豫不决:
  • 极简消息/事件商店-ish :对于域模型发布的每个事件,生成一条仅包含聚合根相关部分的消息(例如,当更新完成时,仅发布有关聚合根更新部分的信息,或多或少匹配最终用户在使用我们的应用程序时所经历的过程)
  • 优点
  • 小消息
  • 非常专业的消息类型
  • 接近“领域事件”
  • 缺点
  • 如果无法保证交货顺序(即,如果在创建消息之前收到更新消息怎么办?)
  • 消费者需要知道要订阅哪些消息类型(可能需要大量列表/领域知识)
  • 如果消费者状态和生产者状态不同步怎么办?
  • 如何处理将来注册但不了解所有过去事件的新消费者
  • 完全包含的幂等消息 :对于域模型发布的每个事件,生成一条包含该时间点聚合根的完整快照的消息,因此实际上只处理两种消息“创建或更新”和“删除”(+元数据与如有必要,提供更具体的信息)
  • 优点
  • 幂等(声明性消息说明“事实就是这样,尽可能同步自己”)
  • 需要维护/处理的消息格式数量较少
  • 允许逐步纠正消费者的同步错误
  • 只要结果消息遵循规范数据模型
  • ,消费者就会自动处理新的领域事件
  • 缺点
  • 更大的消息负载
  • 不那么纯净

  • 你会推荐一种方法吗?

    我们应该考虑另一种方法吗?

    最佳答案

    Is there another approach we should consider ?



    您也可以考虑不要将信息泄露到充当 technical authority 的服务之外。对于那部分业务

    这大致意味着您的事件带有标识符,以便相关方可以知道感兴趣的实体已更改,并且可以查询权限以更新状态。

    for each event published by the Domain Model, generate a message that contains a full snapshot of the Aggregate Root at that point in time



    这也有额外的骗子对聚合表示的任何更改也意味着对作为 API 一部分的消息模式的更改。因此,聚合的内部更改开始跨越您的服务边界。如果您正在实现的聚合对您的业务具有竞争优势,那么您可能希望能够快速适应;涟漪增加了摩擦,会减慢你改变的能力。

    what if consumer state and producer state get out of sync ?



    据我所知,这个问题表明存在设计错误。如果消费者需要状态,也就是说从聚合历史构建的 View ,那么它应该从生产者那里获取该 View ,而不是尝试从观察到的消息集合中组装它。

    也就是说,如果你需要状态,你需要历史(完整的,有序的)。一个事件真正告诉你的是历史已经改变,你可以驱逐你以前缓存的历史。

    同样,对变化的响应能力:如果你改变了生产者的实现,而消费者也试图拼凑他们自己的历史副本,那么你的变化就会跨越服务边界。

    关于rabbitmq - 消息类型 : how much information should messages contain?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39601398/

    相关文章:

    python - 鼠兔与 celery ,连接已关闭

    c# - IDatabaseService 依赖注入(inject)失败?

    c# - 如果接口(interface)是在业务层而不是数据访问层中定义的,您就不会理解它们

    java - 将领域模型与表示分离

    c# - 预定消息

    c - 消息队列: segmentation fault when executing task

    rabbitmq - 使用 rabbitmq 作为 celery 后端的正确配置

    c# - 从 Windows 服务访问新的 RabbitMQ 消息

    ruby-on-rails - rails、redis 和 node.js 的请求处理是如何异步的?

    grails - 用于抛出 UnknownHostException 的 grails 的 RabbitMq 插件