是否有一些指导方针来识别 DDD 中有界上下文的 RabbitMQ 队列
Are there some guidelines for identifying RabbitMQ queues for bounded context in DDD
我即将围绕 RabbitMQ 队列进行域驱动设计,我对此完全陌生。我想知道是否有一些指导方针可以在考虑有界上下文的情况下识别不同的队列。
诸如每个有界上下文一个队列,或有界上下文中每个资源类型一个队列之类的东西。
而且由于队列通常会跨越不同的限界上下文,这让事情变得更加复杂。
有什么建议吗?
每种类型的消费者需要一个队列。
考虑一种处理 E1 和 E2 类型事件的使用者 C1。需要一个队列 Q1,所有 E1 和 E2 类型的事件都被路由到该队列中。如果另一个类型的消费者 C2 处理类型 E3 和 E4 的事件,则需要一个队列 Q2,所有类型 E3 和 E4 的事件都路由到该队列。
我倾向于使用 2 个主要 "concerns"(层)。
对于任何大小合理的软件系统,我会为每个限界上下文使用一个队列,该队列仅与来自相关 BC 的命令有关。处理消息的端点将按照 System.BoundedContextA.Server
行命名,并且该端点将仅处理来自 BoundedContextA
的命令。
对于 BoundedContextA
的任何编排 "owned",我将有另一个 endpoint/queue 处理与编排相关的事件。此端点不仅处理与 BoundedContextA
相关的消息,还处理来自可能与编排有关的其他 BC 的消息。该端点将按照 System.BoundedContextA.Orchestration
.
的方式命名
端点可以水平缩放,使用 RabbitMQ 时尤其容易。
Domain-Driven 设计本身 不规定此类模式 或指南。但它确实规定您围绕您的域设计,而不是围绕代理、队列等基础设施细节
也就是说;并且假设您正在做 OOP,将您的领域对象视为第一个 class 公民可能意味着您将把您的领域与您的基础设施完全分离,从而引入擅长于此的通用模式,例如 hexagonal architecture.
即便如此,DDD 也没有规定特定的集成方法;您询问有关队列的事实表明您正在考虑异步集成。这并没有错,但它总能为 defer architecture decisions. Especially if you are "about to" discover this domain through DDD. Try to start simple, loosely-coupled but monolith-first 带来回报,您可能会发现您甚至根本不需要排队。
考虑到以上所有因素,在与 RabbitMQ 的异步集成场景中,通常使用 pub-sub 模式。所有相关事件都发布到 one 交易所,没有考虑特定的消费者。消费者根据需要设置自己的队列和绑定,因此没有一种公式有效:
- 每个消费者每个事件类型一个队列
- 每个消费者一个队列,具有事件类型或主题模式的多个绑定
- 用于负载平衡的消费者实例之间共享的队列
- ...以及这些的许多组合。
我即将围绕 RabbitMQ 队列进行域驱动设计,我对此完全陌生。我想知道是否有一些指导方针可以在考虑有界上下文的情况下识别不同的队列。
诸如每个有界上下文一个队列,或有界上下文中每个资源类型一个队列之类的东西。
而且由于队列通常会跨越不同的限界上下文,这让事情变得更加复杂。
有什么建议吗?
每种类型的消费者需要一个队列。
考虑一种处理 E1 和 E2 类型事件的使用者 C1。需要一个队列 Q1,所有 E1 和 E2 类型的事件都被路由到该队列中。如果另一个类型的消费者 C2 处理类型 E3 和 E4 的事件,则需要一个队列 Q2,所有类型 E3 和 E4 的事件都路由到该队列。
我倾向于使用 2 个主要 "concerns"(层)。
对于任何大小合理的软件系统,我会为每个限界上下文使用一个队列,该队列仅与来自相关 BC 的命令有关。处理消息的端点将按照 System.BoundedContextA.Server
行命名,并且该端点将仅处理来自 BoundedContextA
的命令。
对于 BoundedContextA
的任何编排 "owned",我将有另一个 endpoint/queue 处理与编排相关的事件。此端点不仅处理与 BoundedContextA
相关的消息,还处理来自可能与编排有关的其他 BC 的消息。该端点将按照 System.BoundedContextA.Orchestration
.
端点可以水平缩放,使用 RabbitMQ 时尤其容易。
Domain-Driven 设计本身 不规定此类模式 或指南。但它确实规定您围绕您的域设计,而不是围绕代理、队列等基础设施细节
也就是说;并且假设您正在做 OOP,将您的领域对象视为第一个 class 公民可能意味着您将把您的领域与您的基础设施完全分离,从而引入擅长于此的通用模式,例如 hexagonal architecture.
即便如此,DDD 也没有规定特定的集成方法;您询问有关队列的事实表明您正在考虑异步集成。这并没有错,但它总能为 defer architecture decisions. Especially if you are "about to" discover this domain through DDD. Try to start simple, loosely-coupled but monolith-first 带来回报,您可能会发现您甚至根本不需要排队。
考虑到以上所有因素,在与 RabbitMQ 的异步集成场景中,通常使用 pub-sub 模式。所有相关事件都发布到 one 交易所,没有考虑特定的消费者。消费者根据需要设置自己的队列和绑定,因此没有一种公式有效:
- 每个消费者每个事件类型一个队列
- 每个消费者一个队列,具有事件类型或主题模式的多个绑定
- 用于负载平衡的消费者实例之间共享的队列
- ...以及这些的许多组合。