【发布时间】:2012-03-28 12:00:31
【问题描述】:
我们希望将 NServiceBus 的发布/订阅功能与 MSMQ 集群一起使用。让我详细解释一下:
- 我们有一个 SQL Server 群集,它还托管 MSMQ 群集。除了 SQL Server 和 MSMQ,我们不能在这个集群上托管任何其他应用程序。这意味着我们的订阅者不允许在集群上运行。
- 我们有多个应用程序服务器托管不同类型的应用程序(从 ASP.NET MVC 到 SharePoint Server 2010)。目标是在所有这些应用程序之间进行发布/订阅。
- 通过 pub/sub 的所有消息都是关键的,并且对业务具有重要价值。这就是为什么我们不想在应用服务器上使用本地队列,但我们想在集群上使用 MSMQ(如果我们丢失了其中一台应用服务器,我们不会冒丢失消息的风险,因为它们在集群上是安全的) .
现在我假设我可以在订阅者端简单地执行以下操作:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
....
</configSections>
<MsmqTransportConfig InputQueue="myqueue@server" ErrorQueue="myerrorqueue"
NumberOfWorkerThreads="1" MaxRetries="5" />
....
</configuration>
我假设这曾经受到支持,请参阅文档:http://docs.particular.net/nservicebus/messaging/publish-subscribe/
但这实际上抛出了一个异常:
启动端点时出现异常,已记录错误。原因: “MsmqTransportConfig”部分中的“InputQueue”条目已过时。经过 默认队列名称取自类命名空间,其中 配置已声明。要覆盖它,请使用 .DefineEndpointName() 使用字符串参数作为队列名称或 Func 参数 返回队列名称。在这种情况下,定义了“myqueue@server” 作为队列名称。
现在,异常清楚地表明我应该使用 DefineEndpointName 方法:
Configure.With()
.DefaultBuilder()
.DefineEndpointName("myqueue@server")
但这会引发另一个记录在案的异常(输入队列应该在同一台机器上):
启动端点时出现异常,已记录错误。原因:输入 queue 必须和这个进程在同一台机器上。
如果我不能在集群上使用 MSMQ,如何确保我的消息是安全的?
调度员!
现在我也一直在研究调度程序,但这似乎也不能解决我的问题。我还假设调度程序无法从远程输入队列中获取消息?除此之外,如果调度员向工作人员发送消息,并且工作人员宕机,我的消息就会丢失(即使它们没有被处理)?
有问题吗?
总而言之,这些是我在 NServiceBus 中的场景中想知道的事情:
- 我希望我的消息在 MSMQ 群集上是安全的,并使用远程输入队列。这是应该做还是不应该做的事情? NServiceBus 可以吗?
- 在这种情况下我应该使用调度程序吗?它可以从远程输入队列中读取吗? (我无法在集群上运行调度程序)
- 如果调度员向工作人员发送消息并且其中一名工作人员出现故障怎么办?我会丢失正在处理的消息吗?
【问题讨论】:
-
您不想在远程队列上运行事务。使队列本地化,或者突袭应用程序驱动器,或者如果你有一个 san,将队列持久化到 san 驱动器而不是本地驱动器。
标签: msmq nservicebus