我们目前开始将事件从一个中央应用程序广播到其他可能感兴趣的消费者应用程序,并且我们团队成员之间对于我们应该在发布的消息中放置多少有不同的选择。
总体思路/架构如下:
- 在生产者应用程序中:
- 用户与可以创建/修改/删除的一些实体(DDD 意义上的聚合根)交互
- 根据正在发生的事情,引发域事件(例如:EntityXCreated、EntityYDeleted、EntityZTransferred 等......即不仅是 CRUD,而且主要是)
- 引发的事件被翻译/转换成我们发送到 RabbitMQ Exchange 的消息
- 在RabbitMQ中 (我们使用的是 RabbitMQ,但我相信这个问题实际上与技术无关):
- 我们为每个消费应用程序定义一个队列
- 绑定将交换连接到消费者队列(可能使用消息过滤)
- 在消费应用程序中
- 应用程序使用并处理其队列中的消息
基于企业集成模式,我们正在尝试为我们发布的消息定义规范格式,并且在两种方法之间犹豫不决:
Minimalist messages / event-store-ish:对于领域模型发布的每个事件,生成一条仅包含聚合根的相关部分的消息(例如,当更新完成时,仅发布有关更新部分的信息聚合根,或多或少与最终用户在使用我们的应用程序时所经历的过程相匹配)
优点
- 小消息大小
- 非常专业的消息类型
- 接近“领域事件”
缺点
- 如果无法保证交货顺序(即如果在创建消息之前收到更新消息怎么办?)
- 消费者需要知道订阅哪些消息类型(可能需要大列表/领域知识)
- 如果消费者状态和生产者状态不同步怎么办?
- 如何处理将来注册但不了解所有过去事件的新消费者
完全包含的幂等消息:对于域模型发布的每个事件,生成一条包含该时间点聚合根的完整快照的消息,因此实际上只处理两种消息“创建或更新”和“删除”(+元数据,如有必要,提供更具体的信息)
优点
- 幂等(声明性消息说明“事实就是这样,尽可能同步自己”)
- 要维护/处理的消息格式数量较少
- 允许逐步纠正消费者的同步错误
- 只要结果消息遵循规范数据模型,消费者就会自动处理新的领域事件
缺点
- 更大的消息负载
- 不太纯
你会推荐一种方法吗?
我们应该考虑另一种方法吗?