Rabbitmq 消息类型:消息应该包含多少信息?

Rabbitmq 消息类型:消息应该包含多少信息?,rabbitmq,domain-driven-design,message-queue,integration-patterns,Rabbitmq,Domain Driven Design,Message Queue,Integration Patterns,目前,我们正在开始将事件从一个中心应用程序广播到其他可能感兴趣的消费者应用程序,我们团队成员之间有不同的选择,关于我们应该在发布的消息中投入多少 总体思路/架构如下: 在生产者应用程序中: 用户与一些可以创建/修改/删除的实体(DDD意义上的聚合根)交互 根据发生的情况,引发域事件(例如:EntityXCreated、EntityYDeleted、EntityZTransferred等,即不仅是CRUD,而且主要是CRUD) 引发的事件被转换为我们发送到RabbitMQ交换机的消息 在Ra

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

总体思路/架构如下:

  • 生产者应用程序中
    • 用户与一些可以创建/修改/删除的实体(DDD意义上的聚合根)交互
    • 根据发生的情况,引发域事件(例如:EntityXCreated、EntityYDeleted、EntityZTransferred等,即不仅是CRUD,而且主要是CRUD)
    • 引发的事件被转换为我们发送到RabbitMQ交换机的消息
  • RabbitMQ(我们正在使用RabbitMQ,但我相信这个问题实际上与技术无关):
    • 我们为每个消费应用程序定义一个队列
    • 绑定将exchange连接到使用者队列(可能带有消息筛选)
  • 在消费应用程序中
    • 应用程序使用并处理其队列中的消息
基于此,我们正在尝试为发布的消息定义规范格式,并在两种方法之间犹豫:

  • 最低限度消息/事件存储ish:对于域模型发布的每个事件,生成仅包含聚合根中相关部分的消息(例如,当更新完成时,只发布有关聚合根目录的更新部分的信息,或多或少与最终用户在使用我们的应用程序时所经历的过程相匹配)

    • 专业人士

      • 小消息大小
      • 非常特殊的消息类型
      • 接近“域事件”
    • 缺点

      • 如果无法保证交付订单,则会出现问题(即,如果在创建消息之前收到更新消息,会怎么样?)
      • 消费者需要知道要订阅哪些消息类型(可能需要大量列表/领域知识)
      • 如果消费国和生产国不同步怎么办
      • 如何处理将来注册但不了解所有过去事件的新消费者
  • 完全包含的幂等ish消息:对于域模型发布的每个事件,生成一条消息,其中包含该时间点聚合根的完整快照,因此实际上只处理“创建或更新”和“删除”两种消息(必要时带有更具体信息的+元数据)

    • 专业人士

      • 幂等式(声明性消息,声明“这就是真相,尽可能地同步您自己”)
      • 要维护/处理的消息格式数量较少
      • 允许逐步更正使用者的同步错误
      • 只要生成的消息遵循规范数据模型,消费者就会自动处理新的域事件
    • 缺点

      • 更大的消息负载
      • 不那么纯洁
  • 你会推荐一种方法吗

    有没有另一种方法我们应该考虑?< /P> 有没有另一种方法我们应该考虑?< /P>

    你也可以考虑不泄露信息,作为业务的一部分,

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

    对于域模型发布的每个事件,生成一条消息,其中包含该时间点聚合根的完整快照


    这还有一个额外的缺点,即对聚合表示的任何更改也意味着对消息架构的更改,消息架构是API的一部分。因此,聚合的内部更改开始波及到您的服务边界。如果您正在实施的聚合代表了您业务部门的竞争优势肌肉,你可能希望能够快速适应;涟漪会增加摩擦,这会减缓你的改变能力

    如果消费国和生产国不同步怎么办

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

    也就是说,如果您需要状态,那么您需要历史记录(完整、有序)。一个事件真正告诉您的是,历史记录已经更改,您可以收回以前缓存的历史记录


    同样,对变化的响应:如果您改变了生产者的实现,而消费者也试图拼凑他们自己的历史记录副本,那么您的变化将波及服务边界。

    -“…您的活动带有标识符,因此相关方可以知道某个实体…已更改,并可以查询权限以获取更新…”->这是有道理的,但在这种情况下,我们是否将消费者与生产者过度耦合?(即生产者必须启动并运行,以便消费者正确完成其工作)对聚合表示的任何更改也意味着对消息架构的更改,消息架构是API“->的一部分,但只要我们只是添加到架构中,这不是一个问题,对吗?不是聚合的所有部分都需要在消息中“如果消费者需要状态,…,那么它应该从生产者获取该视图,“->有道理!我会等几天再接受其他答案;)我会接受