2

在评估一般的排队机制,特别是 Rebus 时,我提出了以下关于 Bus Instances Lifecycle 的问题:

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

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

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

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

我更喜欢通过代码参考/示例来具体回答 Rebus 如何支持或不支持这一点。

4

1 回答 1

4

1:这真的很简单:总线实例(即,它的实现IBus被放入容器中,并在您执行Configure.With(...)配置时交给您)应该是一个单例实例,您在应用程序的整个持续时间内保留它寿命。

不过,您可以轻松创建多个实例,但这仅适用于在同一进程中托管多个 Rebus 端点。

IOW 总线是完全可重入的,可以安全地在 Web 应用程序的线程之间共享。

2:不容易,不 - 至少不是以公共 API 支持的方式。但是您可以这样做:(((RebusBus)bus).SetNumberOfWorkers(0)即,将IBus实例转换为RebusBus并更改工作线程的数量),这将阻塞,直到工作人员的数量调整到所需的数量。

这样,您实际上可以实现您所追求的目标。它只是 Rebus 的官方功能(目前),但它可能会在未来出现。不过,我可以保证,在运行时调整工人数量的能力不会消失。

3:是的,无论您选择哪个持久层,sagas 都受到乐观并发方案的保护。如果您不确定哪种类型的消息将首先到达您的 saga,您应该让您的 saga 容忍这一点 - 即只需IAmInitiatedBy<>为每个可能启动的消息类型实现并让 saga 正确处理。

(相当)容忍乱序消息是一个很好的一般稳健性原则,当消息在错误队列中停留一段时间后重新传递时,它也会很好地为您服务。

4:即使您使用多个总线实例,Rebus 也会获取当前消息上下文,因为它使用“环境上下文”(即MessageContext安装在工作线程上的实例)来获取您发送消息的事实在处理程序中,这反过来会导致已处理消息的相关 ID 被复制到任何传出消息。

这样bus.Reply也行。

但正如我在 (1) 中所说,总线实例是完全可重入的,不需要有多个实例,除非它们实际上是逻辑上不同的端点。

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

于 2014-07-31T05:24:48.870 回答