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

时间:2016-09-20 18:35:29

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

我们目前正在开始将活动从一个中央应用程序广播到其他可能感兴趣的消费者应用程序,我们团队成员之间有不同的选择我们应该在发布的消息中加入多少。< / p>

总体思路/架构如下:

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

基于Enterprise Integration Patterns我们正在尝试为发布的消息定义 Canonical格式,并且在两种方法之间犹豫不决:

  1. 极简主义消息 / event-store-ish :对于域模型发布的每个事件,生成仅包含聚合根部分的消息相关的(例如,更新完成时,只发布有关聚合根的更新部分的信息,或多或少与最终用户在使用我们的应用程序时经历的过程相匹配)

    • 赞成

      • 小邮件大小
      • 非常专业的消息类型
      • 接近&#34;域事件&#34;
    • 缺点

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

    • 赞成

      • 幂等(声明性消息陈述&#34;这就是事实,然而你可以同步自己&#34;)
      • 维护/处理的消息格式数量较少
      • 允许逐步纠正消费者的同步错误
      • 消费者自动处理新的域事件,只要生成的消息遵循规范数据模型
    • 缺点

      • 更大的消息有效负载
  3. 你会推荐一种方法吗?

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

1 个答案:

答案 0 :(得分:4)

  

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

您可能还会考虑不将该信息从服务中泄露出来作为该部分业务的technical authority

这大致意味着您的事件带有标识符,以便感兴趣的各方可以知道感兴趣的实体已经更改,并且可以向权威机构查询该州的更新。

  

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

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

  

如果消费者状态和生产者状态不同步怎么办?

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

也就是说,如果您需要州,则需要历史(完整,有序)。所有单个事件都会告诉您历史记录已经改变,您可以逐出历史记录。

同样,对变化的响应:如果你改变了生产者的实现,消费者也试图拼凑他们自己的历史副本,那么你的变化就会在服务范围内波动。