总线实例生命周期和最佳实践

时间:2014-07-30 21:09:28

标签: c# .net rebus

虽然总体上考虑了排队机制,特别是Rebus,但我提出了以下有关Bus Instances Lifecycle的问题:

  1. 当需要从Windows服务上托管的多个WCF服务访问Bus实例(单向客户端模式)时,实例化的唯一选择是Singleton模式吗?

  2. 有一种方法可以暂停一个总线(停止向消息处理程序发送消息?)然后重新启动它。或者唯一的选择是处置它并创建一个新的。

    • 用例就是当您连接到具有吞吐量限制或每小时事务限制的系统时。
  3. 如果sagas有多个工作人员,如果是这样,并且假设事件是按照正确的顺序发送的(发起者优先),那么可以保证首先处理发起人,然后创建传奇,在多个工人处理以下事件之前?

  4. 如果在同一主机中,使用了几个总线实例,并且在消息处理程序中,我们基于相同的配置在另一个总线实例上调用send。相关id不会被传输,而回复之类的东西也不能正常工作,对吗?

  5. 我更喜欢Rebus如何通过代码参考/示例来支持或不支持。

1 个答案:

答案 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)中所述,总线实例是完全可重入的,并且不需要有多个实例,除非它们实际上是逻辑上不同的端点。

我希望这能回答你的问题:)