使用 NServiceBus 实现发布-订阅通道

Implementing a A Publish-Subscribe Channel using NServiceBus

我正在尝试使用 NServiceBus 实现发布-订阅通道。根据 Enterprise Integration Patterns 一书,Pulish-Subscribe Channel 被描述为:

A Publish-Subscribe Channel works like this: It has one input channel that splits into multiple output channels, one for each subscriber. When an event is published into the channel, the Publish-Subscribe Channel delivers a copy of the message to each of the output channels. Each output end of the channel has only one subscriber, which is allowed to consume a message only once. In this way, each subscriber gets the message only once, and consumed copies disappear from their channels.

Hohpe, Gregor; Woolf, Bobby (2012-03-09). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions (Addison-Wesley Signature Series (Fowler)) (Kindle Locations 2880-2883). Pearson Education. Kindle Edition.”

有一个包含发布者和订阅者的样本:http://docs.particular.net/samples/step-by-step/。我已经为版本 5 构建了示例解决方案。然后我 运行 多个订阅者在不同的命令行 windows 中查看系统的行为方式。

即使有多个订阅者,也只有一个订阅者收到发布的事件。发布多个事件导致最多一个订阅者处理该事件。

我找不到有关如何将 NServiceBus 配置为引用文本中定义的发布-订阅通道的任何信息。有谁知道如何做到这一点?不支持吗?

[2016 年 2 月 2 日更新]

复制订阅者后我没有重命名我的端点。这给了我想要的行为。

订阅者需要先启动才能发送他们有兴趣订阅事件的消息。然后发布者需要启动,有时间处理订阅消息。存储所有订阅后,您才能发布消息。如果您在所有订阅实际存储之前发布消息,NServiceBus 只会将消息发送给它已经知道的订阅者。一秒钟后可能会知道所有订阅者,但到那时您已经发布了消息。

使用持久性时,如 SQL 服务器或类似的东西,订阅将被存储和保留。因此,在重新启动服务后,所有订阅者立即都是已知的。使用 in-memory 存储,每次重新启动发布者时,订阅都会丢失。因此需要稍等片刻,直到所有订阅都是进程,时间更长。

并非每个订阅者都实际发送消息也可能是一个问题,因为您可能配置错误。

written a tutorial 我自己也有帮助。

如果您是 运行 同一订阅者的多个实例,那么您所描述的就是预期的功能。

场景

1 个发布者,1 个逻辑订阅者

一些处理者发布了一个事件并且电子邮件处理者订阅了该事件。当电子邮件处理程序使用该事件时,电子邮件处理程序将发送一封电子邮件。在这种情况下,只有一个逻辑订阅者,即电子邮件处理者。因此,只发送一份活动副本。

1 个发布者,2 个逻辑订阅者

在下一个场景中,有两个逻辑订阅者:发票处理程序和电子邮件处理程序。当处理器发布一个事件时,会发送该事件的两个副本。一份给发票处理员,一份给电子邮件处理员。

1 个发布者,1 个逻辑订阅者的 2 个实例

在这种情况下,即使有两个服务订阅了事件,也只有一个逻辑订阅者。在这种情况下,只会发送一个事件副本,并且只有一个电子邮件处理程序会处理该事件。如果两个电子邮件处理程序都处理了该事件,那么您将为订阅者的 N 个实例完成 N 个操作。换句话说,将发送两封电子邮件而不是一封。这种情况很可能需要两个电子邮件处理程序,因为单个处理程序无法跟上处理器的负载,或者需要冗余。

总结

如果您只是启动同一订阅者的多个实例,您仍然只有一个订阅者处理该事件。这是设计使然。否则,每个额外的过程都会重复这项工作。

如果您想看到两个逻辑订阅者,请在该解决方案中创建一个新项目,使用不同的名称,并订阅相同的事件(在代码中或使用配置文件)。然后启动发布者和每个订阅者的一个实例。发布者发布事件后,您会看到两个订阅者都在处理该事件。