2012-07-05 41 views
3

我目前正在调查使用NServiceBus解决以下问题。我只是想确保我不会在这个兔子洞里走。多线程CQRS与NServiceBus

我有一个基于CQRS架构的解决方案。本质上,我有一系列命令通过NServiceBus传递给端点,我执行一些处理来改变聚合根的状态,然后发出一系列事件来通知系统其余部分的变化。

我的问题是,这一切都很好的一个线程,我不需要担心锁定任何给定的聚合根,而我改变状态。

我们已经到了一个线程不会削减它的地步,我需要开始研究使用多个工作线程/进程来处理消息。

根据我可以同时处理多个聚合根的事实,有一个自然的任务分解,但是我不能同时处理同一个聚合根的多个消息,因为这会导致高由于收到消息的速度而导致的争用。

我想避免这种情况,我需要锁定一个特定的聚合根ID,而是将一个聚合根分配给队列/线程/进程,这将确保来自同一聚合根的所有消息都被同步处理。

我正在使用NServiceBus的Pub/Sub模型发布事件。就我所看到的问题而言,这些事件需要从同一端点发布,即使该消息的处理可能委托给另一个端点。即当我实际上在“MyDomainQueue-Worker1”上处理消息时,我需要欺骗系统认为消息是从“MyDomainQueue”发布的。

我的计划是创建一个自定义分配器,它允许主端点将消息处理委托给工作端点。分发者将以循环方式为任何给定的聚合根分配一个队列。主要端点将向这些工作人员发送命令,处理将发生,并且工作人员将回复一系列事件。主要终端会将这些事件重新发布到公交车上。

我在寻找一些关于这种方法的反馈。感觉就像我正在努力工作一样,我只想检查是否有其他人处理了类似的问题。也许NServiceBus是这个工作的错误工具,或者我的方法可能是错误的。任何和所有的反馈是受欢迎的。

谢谢,

PS - 我也有在其周围将需要上述的溶液中的构型的量的担忧。

+1

你看看内置的分销商吗?有关3/4下面的内容,请参阅下面的页面,它描述了一个扩展的Pub/Sub模型。 http://nservicebus.com/DistributorV3.aspx –

回答

1

关于发布来自不同端点的事件,我认为您对于从一个服务发布的事件的概念有点太过兴趣。仅在逻辑意义上这是真实的 - 一个事件应该完全由一个逻辑服务拥有,然而逻辑服务可以由许多端点组成。

事件并非真正从队列中发布。当你想到发布事件的队列时,你真正在谈论的是你发送该事件订阅请求的输入队列。

因此,只要对该事件的订阅请求都发送到同一个地方,就可以让多个端点都发布相同的事件。

例如,在批量与优先级​​情况下,您有两个端点处理相同的命令(然后发布相同的事件),除了一个批量使用长SLA,而另一个有一个更短的SLA - 也许它是一个大客户,或者命令来自实际的用户等待响应。 QueueA和PriorityQueueA都处理相同的命令并发布相同的事件,但QueueA处理订阅,因此两个进程都从QueueA“发布”。

这就是说,你有没有试图让多个线程访问聚合根?即使有一些争议,你可能会发现只要少量重试就可能没有你想象的那么有争议。在NServiceBus的生产环境中,我有一些相当有争议的进程,虽然我偶尔会看到争用的证据是日志中的一个异常,但有5次重试,我从来没有任何进展到错误队列。

- 最近,增加了二级重试功能,这进一步降低了错误队列中消息结束的机会。

如果存在很多争用,另一种策略可能是维护目前正在操作的聚合根目录的内存列表,然后如果出现应该“锁定”的消息,则只需拨打Bus.HandleCurrentMessageLater()即可坚持消息返回到队列末尾。

+0

感谢您的建议。我将陷入对poc的进展提供反馈。 Bus.HandleCurrentMessageLater()让我思考。我应该能够与此合作。 –

+0

只是关于具有多个端点的逻辑服务的问题。这是否意味着订阅者需要在两个(所有)端点上订阅相同的事件? –

+0

不,订阅者订阅(或者说,发送订阅请求到)一个逻辑授权源。这就是订阅存储的地方。然后,多个*物理*端点可以将同一事件发布为一个统一*逻辑*发布者。 –