如何在两端横向扩展 NServiceBus?

How to scale out NServiceBus on either end?

我试图了解 NServiceBus 在各种情况下如何扩展的概述,但我未能在那里找到足够的信息。

通常,在 pub/sub 场景中横向扩展 NServiceBus(和底层传输)似乎与在 send/receive 场景中不同。此外,消息发送系统是否横向扩展或 "absorbing" 系统是否横向扩展似乎有所不同。

考虑使用 MSMQ 作为传输层和 NServiceBus 在上面的设置,并假设我们将使用队列 MyQueue 作为从发射系统到吸收系统的通信通道(通过 send/receive 或 pub/sub)。在以下情况下,横向扩展设置会是什么样子?我试过在下面给出一些答案,但我不确定。

简而言之,如果能大致了解一下推荐的 NServiceBus 是如何针对上述四种情况设置的,那就太好了。

您可以将工作节点添加到任何 NServiceBus 端点。必须做出的选择是主节点是否也处理消息。根据您的情况,您可以选择其中之一。 Distributor角色用于Master节点不处理消息,而是充当调度员的场景。

使用发送与发布的主要区别在于对订阅存储的依赖性。发布时,您需要一个外部存储机制,如果有新订阅者,则必须在每次发布时查询此存储。这有与之相关的开销。发布时,您应该通过主节点订阅,它将根据上述配置确定是否处理消息。

当向外扩展发布者时,Master 和 Worker 都将与 Subscription 存储对话并以循环方式执行发布。 Master节点知道Workers是否忙,并相应地分配负载。

如果正在交换的消息对其他端点没有任何意义,您可以考虑坚持点对点通信(发送)以消除与发布相关的开销。

首先,重要的是要认识到 NServiceBus 中的分发器组件仅在扩展 MSMQ 传输时相关。其他支持的传输是代理并使用竞争消费模式达到同样的结果。

其次,您需要了解 NServiceBus 区分逻辑自治 component/endpoint 和它的物理部署 。当您发送、发布或订阅时,您仅使用端点的逻辑地址。逻辑地址通常与物理地址相同,但并非必须如此。一项服务只能有一个逻辑端点地址,但可以有多个物理部署。

在非缩放场景下,也是一样的。假设 ServiceAServiceB 部署到机器 Machine1ServiceA 的逻辑端点地址和物理地址将为 ServiceA@Machine1。 ServiceB 的逻辑地址和物理地址为 ServiceB@Machine1

在横向扩展的场景中,这会有所不同。假设您实际将 ServiceAServiceB 部署到 Machine1Machine2。您还将 ServiceAServiceB 的两个分发服务器部署到第三台机器 MachineXServiceA 现在有一个逻辑端点地址 ServiceA@MachineX,但有两个物理地址:ServiceA@Machine1ServiceA@Machine2ServiceB 也有一个逻辑端点地址 ServiceB@MachineX 和两个物理地址:ServiceB@Machine1ServiceB@Machine2

输入分发器。它是一个简单的负载均衡器。它从服务的逻辑端点获取传入消息,并将它们转发到物理 endpoints/workers 之一。它将以循环方式分配负载。

使这项工作成功的诀窍是在发送、订阅或发布某些内容时始终使用要到达的组件的逻辑端点地址。切勿直接使用单个端点部署的物理地址。

让我们看一个简单的发送。 ServiceA 想发送一些东西给 ServiceBServiceA 的物理端点之一,在 Machine1 上,将创建一条消息并将其放入 ServiceBServiceB@MachineX 的逻辑地址中。该消息包含发送方的物理和逻辑端点地址。 MachineXServiceB 的分发者将接收消息并将其传递给 ServiceB@Machine1ServiceB@Machine2。而已。这就是分销商所做的一切。

订阅的工作方式相同。假设 ServiceA 想要订阅 ServiceB 的活动之一。 ServiceA 的物理端点之一向 ServiceBServiceB@MachineX 的逻辑端点地址发送订阅消息。该消息主要包含以下内容“ServiceA 想订阅 event XXX”。分发者获取订阅消息并将其交给 ServiceB@Machine1ServiceB@Machine2。幸运工人查看消息并存储逻辑 ServiceA 想要订阅 event XXX 的事实。请注意,它存储的是逻辑端点地址,而不是恰好发送订阅消息的 ServiceA 物理部署的端点地址。 订阅存储属于逻辑 ServiceB 端点,并在它的所有物理部署之间共享。这排除了 MSMQ 作为存储。支持的商店是 NHibernate 或 RavenDB。(与原生 pub/sub-support 的传输有点不同,但这不是重点。)

发布类似。ServiceB想发布XXX eventServiceB 的其中一项物理部署会查看订阅数据库以查找对 event XXX 的订阅。它看到 ServiceA@MachineX 处的逻辑端点地址对该事件感兴趣。然后它将事件放入该队列。 MachineXServiceA 的分发者获取消息并将其分发给其中一名工作人员。

分发服务器本身无法横向扩展,但如果不使其具有高可用性,它就会成为单点故障。 The recommendation is to use a Windows Failover Cluster 经销商及其 MSMQ。

还有主节点的概念。将其视为同一物理进程中的分发服务器和工作人员 运行,以优化托管 Windows 故障转移集群的机器上的资源使用。以上所有内容仍然适用于主节点。