如何在两端横向扩展 NServiceBus?
How to scale out NServiceBus on either end?
我试图了解 NServiceBus 在各种情况下如何扩展的概述,但我未能在那里找到足够的信息。
通常,在 pub/sub 场景中横向扩展 NServiceBus(和底层传输)似乎与在 send/receive 场景中不同。此外,消息发送系统是否横向扩展或 "absorbing" 系统是否横向扩展似乎有所不同。
考虑使用 MSMQ 作为传输层和 NServiceBus 在上面的设置,并假设我们将使用队列 MyQueue
作为从发射系统到吸收系统的通信通道(通过 send/receive 或 pub/sub)。在以下情况下,横向扩展设置会是什么样子?我试过在下面给出一些答案,但我不确定。
发射系统未缩放;未缩放的吸收系统: 这是简单的设置,两端有一个端点,接收端有一个队列。
两个系统的订阅存储:MSMQ
发射系统未缩放;吸收系统缩放: 吸收系统的单个节点,即端点,是 "promoted" 作为 Distributor 并且许多工作节点从该单个分发节点获取消息。
吸收系统订阅或接收有区别吗?
分发服务器也可以横向扩展吗?
documentation 建议使用单独的队列名称,但如果 sending/publishing 系统应该关心接收系统是否横向扩展,这不是很麻烦吗?从发送方的角度来看,我认为接收方的横向扩展应该是透明的。
两个系统的订阅存储:MSMQ? 订阅存储在哪里?在经销商处?
发射系统缩放;未缩放的吸收系统: 发射系统的多个节点可以 发送 到未缩放的吸收系统,就像上面的 unscaled/unscaled 场景一样。但是发射系统的多个节点不能(或不应该)发布到同一个吸收系统?或者是什么?如何处理来自多个节点的发布?
两个系统的订阅存储:MSMQ?
发射系统缩放;吸收系统缩放: 这只是上述两种情况的组合,用于 send/receive 和 pub/sub 划线模式?
两个系统的订阅存储:MSMQ?
简而言之,如果能大致了解一下推荐的 NServiceBus 是如何针对上述四种情况设置的,那就太好了。
您可以将工作节点添加到任何 NServiceBus 端点。必须做出的选择是主节点是否也处理消息。根据您的情况,您可以选择其中之一。 Distributor角色用于Master节点不处理消息,而是充当调度员的场景。
使用发送与发布的主要区别在于对订阅存储的依赖性。发布时,您需要一个外部存储机制,如果有新订阅者,则必须在每次发布时查询此存储。这有与之相关的开销。发布时,您应该通过主节点订阅,它将根据上述配置确定是否处理消息。
当向外扩展发布者时,Master 和 Worker 都将与 Subscription 存储对话并以循环方式执行发布。 Master节点知道Workers是否忙,并相应地分配负载。
如果正在交换的消息对其他端点没有任何意义,您可以考虑坚持点对点通信(发送)以消除与发布相关的开销。
首先,重要的是要认识到 NServiceBus 中的分发器组件仅在扩展 MSMQ 传输时相关。其他支持的传输是代理并使用竞争消费模式达到同样的结果。
其次,您需要了解 NServiceBus 区分逻辑自治 component/endpoint 和它的物理部署 。当您发送、发布或订阅时,您仅使用端点的逻辑地址。逻辑地址通常与物理地址相同,但并非必须如此。一项服务只能有一个逻辑端点地址,但可以有多个物理部署。
在非缩放场景下,也是一样的。假设 ServiceA
和 ServiceB
部署到机器 Machine1
。 ServiceA
的逻辑端点地址和物理地址将为 ServiceA@Machine1
。 ServiceB 的逻辑地址和物理地址为 ServiceB@Machine1
。
在横向扩展的场景中,这会有所不同。假设您实际将 ServiceA
和 ServiceB
部署到 Machine1
和 Machine2
。您还将 ServiceA
和 ServiceB
的两个分发服务器部署到第三台机器 MachineX
。 ServiceA
现在有一个逻辑端点地址 ServiceA@MachineX
,但有两个物理地址:ServiceA@Machine1
和 ServiceA@Machine2
。 ServiceB
也有一个逻辑端点地址 ServiceB@MachineX
和两个物理地址:ServiceB@Machine1
和 ServiceB@Machine2
。
输入分发器。它是一个简单的负载均衡器。它从服务的逻辑端点获取传入消息,并将它们转发到物理 endpoints/workers 之一。它将以循环方式分配负载。
使这项工作成功的诀窍是在发送、订阅或发布某些内容时始终使用要到达的组件的逻辑端点地址。切勿直接使用单个端点部署的物理地址。
让我们看一个简单的发送。 ServiceA
想发送一些东西给 ServiceB
。 ServiceA
的物理端点之一,在 Machine1
上,将创建一条消息并将其放入 ServiceB
、ServiceB@MachineX
的逻辑地址中。该消息包含发送方的物理和逻辑端点地址。 MachineX
上 ServiceB
的分发者将接收消息并将其传递给 ServiceB@Machine1
或 ServiceB@Machine2
。而已。这就是分销商所做的一切。
订阅的工作方式相同。假设 ServiceA
想要订阅 ServiceB
的活动之一。 ServiceA
的物理端点之一向 ServiceB
、ServiceB@MachineX
的逻辑端点地址发送订阅消息。该消息主要包含以下内容“ServiceA
想订阅 event XXX
”。分发者获取订阅消息并将其交给 ServiceB@Machine1
或 ServiceB@Machine2
。幸运工人查看消息并存储逻辑 ServiceA
想要订阅 event XXX
的事实。请注意,它存储的是逻辑端点地址,而不是恰好发送订阅消息的 ServiceA
物理部署的端点地址。 订阅存储属于逻辑 ServiceB
端点,并在它的所有物理部署之间共享。这排除了 MSMQ 作为存储。支持的商店是 NHibernate 或 RavenDB。(与原生 pub/sub-support 的传输有点不同,但这不是重点。)
发布类似。ServiceB
想发布XXX event
。 ServiceB
的其中一项物理部署会查看订阅数据库以查找对 event XXX
的订阅。它看到 ServiceA@MachineX
处的逻辑端点地址对该事件感兴趣。然后它将事件放入该队列。 MachineX
上 ServiceA
的分发者获取消息并将其分发给其中一名工作人员。
分发服务器本身无法横向扩展,但如果不使其具有高可用性,它就会成为单点故障。 The recommendation is to use a Windows Failover Cluster 经销商及其 MSMQ。
还有主节点的概念。将其视为同一物理进程中的分发服务器和工作人员 运行,以优化托管 Windows 故障转移集群的机器上的资源使用。以上所有内容仍然适用于主节点。
我试图了解 NServiceBus 在各种情况下如何扩展的概述,但我未能在那里找到足够的信息。
通常,在 pub/sub 场景中横向扩展 NServiceBus(和底层传输)似乎与在 send/receive 场景中不同。此外,消息发送系统是否横向扩展或 "absorbing" 系统是否横向扩展似乎有所不同。
考虑使用 MSMQ 作为传输层和 NServiceBus 在上面的设置,并假设我们将使用队列 MyQueue
作为从发射系统到吸收系统的通信通道(通过 send/receive 或 pub/sub)。在以下情况下,横向扩展设置会是什么样子?我试过在下面给出一些答案,但我不确定。
发射系统未缩放;未缩放的吸收系统: 这是简单的设置,两端有一个端点,接收端有一个队列。
两个系统的订阅存储:MSMQ
发射系统未缩放;吸收系统缩放: 吸收系统的单个节点,即端点,是 "promoted" 作为 Distributor 并且许多工作节点从该单个分发节点获取消息。
吸收系统订阅或接收有区别吗?
分发服务器也可以横向扩展吗?
documentation 建议使用单独的队列名称,但如果 sending/publishing 系统应该关心接收系统是否横向扩展,这不是很麻烦吗?从发送方的角度来看,我认为接收方的横向扩展应该是透明的。
两个系统的订阅存储:MSMQ? 订阅存储在哪里?在经销商处?
发射系统缩放;未缩放的吸收系统: 发射系统的多个节点可以 发送 到未缩放的吸收系统,就像上面的 unscaled/unscaled 场景一样。但是发射系统的多个节点不能(或不应该)发布到同一个吸收系统?或者是什么?如何处理来自多个节点的发布?
两个系统的订阅存储:MSMQ?
发射系统缩放;吸收系统缩放: 这只是上述两种情况的组合,用于 send/receive 和 pub/sub 划线模式?
两个系统的订阅存储:MSMQ?
简而言之,如果能大致了解一下推荐的 NServiceBus 是如何针对上述四种情况设置的,那就太好了。
您可以将工作节点添加到任何 NServiceBus 端点。必须做出的选择是主节点是否也处理消息。根据您的情况,您可以选择其中之一。 Distributor角色用于Master节点不处理消息,而是充当调度员的场景。
使用发送与发布的主要区别在于对订阅存储的依赖性。发布时,您需要一个外部存储机制,如果有新订阅者,则必须在每次发布时查询此存储。这有与之相关的开销。发布时,您应该通过主节点订阅,它将根据上述配置确定是否处理消息。
当向外扩展发布者时,Master 和 Worker 都将与 Subscription 存储对话并以循环方式执行发布。 Master节点知道Workers是否忙,并相应地分配负载。
如果正在交换的消息对其他端点没有任何意义,您可以考虑坚持点对点通信(发送)以消除与发布相关的开销。
首先,重要的是要认识到 NServiceBus 中的分发器组件仅在扩展 MSMQ 传输时相关。其他支持的传输是代理并使用竞争消费模式达到同样的结果。
其次,您需要了解 NServiceBus 区分逻辑自治 component/endpoint 和它的物理部署 。当您发送、发布或订阅时,您仅使用端点的逻辑地址。逻辑地址通常与物理地址相同,但并非必须如此。一项服务只能有一个逻辑端点地址,但可以有多个物理部署。
在非缩放场景下,也是一样的。假设 ServiceA
和 ServiceB
部署到机器 Machine1
。 ServiceA
的逻辑端点地址和物理地址将为 ServiceA@Machine1
。 ServiceB 的逻辑地址和物理地址为 ServiceB@Machine1
。
在横向扩展的场景中,这会有所不同。假设您实际将 ServiceA
和 ServiceB
部署到 Machine1
和 Machine2
。您还将 ServiceA
和 ServiceB
的两个分发服务器部署到第三台机器 MachineX
。 ServiceA
现在有一个逻辑端点地址 ServiceA@MachineX
,但有两个物理地址:ServiceA@Machine1
和 ServiceA@Machine2
。 ServiceB
也有一个逻辑端点地址 ServiceB@MachineX
和两个物理地址:ServiceB@Machine1
和 ServiceB@Machine2
。
输入分发器。它是一个简单的负载均衡器。它从服务的逻辑端点获取传入消息,并将它们转发到物理 endpoints/workers 之一。它将以循环方式分配负载。
使这项工作成功的诀窍是在发送、订阅或发布某些内容时始终使用要到达的组件的逻辑端点地址。切勿直接使用单个端点部署的物理地址。
让我们看一个简单的发送。 ServiceA
想发送一些东西给 ServiceB
。 ServiceA
的物理端点之一,在 Machine1
上,将创建一条消息并将其放入 ServiceB
、ServiceB@MachineX
的逻辑地址中。该消息包含发送方的物理和逻辑端点地址。 MachineX
上 ServiceB
的分发者将接收消息并将其传递给 ServiceB@Machine1
或 ServiceB@Machine2
。而已。这就是分销商所做的一切。
订阅的工作方式相同。假设 ServiceA
想要订阅 ServiceB
的活动之一。 ServiceA
的物理端点之一向 ServiceB
、ServiceB@MachineX
的逻辑端点地址发送订阅消息。该消息主要包含以下内容“ServiceA
想订阅 event XXX
”。分发者获取订阅消息并将其交给 ServiceB@Machine1
或 ServiceB@Machine2
。幸运工人查看消息并存储逻辑 ServiceA
想要订阅 event XXX
的事实。请注意,它存储的是逻辑端点地址,而不是恰好发送订阅消息的 ServiceA
物理部署的端点地址。 订阅存储属于逻辑 ServiceB
端点,并在它的所有物理部署之间共享。这排除了 MSMQ 作为存储。支持的商店是 NHibernate 或 RavenDB。(与原生 pub/sub-support 的传输有点不同,但这不是重点。)
发布类似。ServiceB
想发布XXX event
。 ServiceB
的其中一项物理部署会查看订阅数据库以查找对 event XXX
的订阅。它看到 ServiceA@MachineX
处的逻辑端点地址对该事件感兴趣。然后它将事件放入该队列。 MachineX
上 ServiceA
的分发者获取消息并将其分发给其中一名工作人员。
分发服务器本身无法横向扩展,但如果不使其具有高可用性,它就会成为单点故障。 The recommendation is to use a Windows Failover Cluster 经销商及其 MSMQ。
还有主节点的概念。将其视为同一物理进程中的分发服务器和工作人员 运行,以优化托管 Windows 故障转移集群的机器上的资源使用。以上所有内容仍然适用于主节点。