NServiceBus端点是否可以订阅同一消息的多个发布者?

时间:2012-01-26 15:43:10

标签: c# nservicebus publish-subscribe

我正在开发一个系统来支持从各种硬件类型中接收状态信息。每个硬件都报告相同的状态信息(纬度,经度),但每种硬件类型都使用唯一的协议来报告此信息。出于这个原因,我有多个服务,每个设备类型一个,监听和解析该设备的协议。我希望每个服务都使用一条公共消息发布状态信息:

public interface IPositionMessage : IMessage
{
   string UnitName { get; set; }
   double Latitude { get; set; }
   double Longitude { get; set; }
}

我在设置我的第一个服务时没有遇到任何问题,但现在我正在设置我的第二个服务,我发现我的订阅者无法订阅来自多个发布者的相同消息。

在类似的question on the NServiceBus yahoo group中,建议的解决方案是将公共消息转换为命令并使用Bus.Send而不是Bus.Publish。我觉得在这种情况下没有意义,因为真正发生的事情是一个事件(该单位已经到达一个位置并报告新的位置)。如果我要将此转换为命令,我需要提前知道此事件的所有潜在订阅者,我不这样做。另一种可能的解决方案是创建一个聚合/重新发布者,每个服务将Bus.Send,然后该消息将从单个发布者重新发布。这似乎是一个不必要的瓶颈。

是否有任何方法允许订阅者订阅来自多个发布者的同一邮件?

2 个答案:

答案 0 :(得分:12)

这是Udi试图让你很难逃脱的那些SOA“成功之谜”之一。

基本的二元性是:

  • 命令应该由许多客户发送,并由一个权威来源接收。
  • 事件应由单一权威来源发布,并由许多客户接收。

但是这个权威来源是一个LOGICAL权威来源。重要的是,如果我对所有IPositionMessage数据感兴趣,那么我应该只有一个逻辑点(queuename @ servername)发送我的订阅请求。

这并不意味着同一逻辑服务中的多个物理处理器不能全部发布相同的事件类型,只要它们发布的内容具有权威性。

关键是所有物理处理器必须共享相同的订阅存储。实际上,您可能希望只有一个物理端点处理订阅请求,而根本不处理任何处理。它只接收订阅请求(QueueX @ ServerY对IPositionMessage感兴趣)并更新订阅存储。

然后,绑定到相同订阅存储的每个处理器都会发布IPositionMessage,并会发现QueueX @ ServerY感兴趣,并将该事件的副本发送到该位置。

在运行NServiceBus.Lite配置文件的开发环境中,这有点难以接受,因为默认情况下订阅存储在内存中,所以很明显它不会被共享,也不会显示正常运行,所以要做好准备。

答案 1 :(得分:1)

虽然可以订阅多个发布者(可以在<unicastBusConifg />中配置),但我同意用户组的意见,因为这应该成为逻辑发送而不是发布。

我不知道为什么我会这么想。