虽然总体上考虑了排队机制,特别是Rebus,但我提出了以下有关Bus Instances Lifecycle的问题:
当需要从Windows服务上托管的多个WCF服务访问Bus实例(单向客户端模式)时,实例化的唯一选择是Singleton模式吗?
有一种方法可以暂停一个总线(停止向消息处理程序发送消息?)然后重新启动它。或者唯一的选择是处置它并创建一个新的。
如果sagas有多个工作人员,如果是这样,并且假设事件是按照正确的顺序发送的(发起者优先),那么可以保证首先处理发起人,然后创建传奇,在多个工人处理以下事件之前?
如果在同一主机中,使用了几个总线实例,并且在消息处理程序中,我们基于相同的配置在另一个总线实例上调用send。相关id不会被传输,而回复之类的东西也不能正常工作,对吗?
我更喜欢Rebus如何通过代码参考/示例来支持或不支持。
答案 0 :(得分:3)
1:它非常简单:总线实例(即IBus
的实现被放入容器并在你执行Configure.With(...)
配置法术时交给你)是应该是一个单例实例,你可以在整个应用程序的整个生命周期内保持这种情况。
您可以轻松创建多个实例,但这仅适用于在同一进程中托管多个Rebus端点。
IOW总线是完全可重入的,可以安全地在Web应用程序中的线程之间共享。
2:不容易,不 - 至少不是以公共API支持的方式。您可以执行此操作:((RebusBus)bus).SetNumberOfWorkers(0)
(即将IBus
实例强制转换为RebusBus
并更改工作线程数),这将阻塞直到数量为工人已经调整到所需的数量。
通过这种方式,您实际上可以实现您所追求的目标。它不仅仅是Rebus的官方功能,但它可能在未来。但我可以保证,在运行时调整工人数量的能力不会消失。
3:是的,无论你选择哪种持久层,sagas都会受到乐观并发方案的保护。如果你不确定哪种类型的消息会首先到达你的传奇,那么你应该让你的saga容忍这个 - 即只为每个潜在的启动消息类型实现IAmInitiatedBy<>
并使正确的传奇句柄。 / p>
对无序消息的(相当)容忍是一个很好的通用健壮性原则,当在错误队列中停留一段时间后重新传递消息时,它也能很好地为您服务。
4:即使您使用多个总线实例,Rebus也会选择当前的消息上下文,因为它使用"ambient context"(即工作线程上安装的MessageContext
实例)来选择您从处理程序中发送消息的事实,这反过来将导致处理消息的相关ID被复制到任何外发消息。
因此bus.Reply
也可以。
但正如我在(1)中所述,总线实例是完全可重入的,并且不需要有多个实例,除非它们实际上是逻辑上不同的端点。
我希望这能回答你的问题:)