【问题标题】:How to scale out NServiceBus on either end?如何在两端横向扩展 NServiceBus?
【发布时间】:2015-08-06 15:17:57
【问题描述】:

我试图了解 NServiceBus 如何在各种场景中横向扩展,但我未能找到足够的信息。

通常,在发布/订阅场景中横向扩展 NServiceBus(和底层传输)似乎与在发送/接收场景中不同。此外,消息发送系统是横向扩展还是“吸收”系统横向扩展似乎会有所不同。

考虑一个设置,MSMQ 作为传输层,NServiceBus 在顶部,并假设我们将使用队列MyQueue 作为从发射系统到吸收系统的通信通道(通过发送/接收或发布/订阅)。在以下场景中,横向扩展设置的外观如何?我已经尝试在下面提出一些答案,但不确定。

  • 发射系统未缩放;吸收系统未缩放: 这是一个简单的设置,两端有一个端点,接收端有一个队列。

    两个系统的订阅存储:MSMQ

  • 发射系统未缩放;吸收系统扩展:吸收系统中的单个节点(端点)被“提升”为Distributor,并且许多工作节点从该单个分发器节点获取消息。

    吸收系统订阅还是接收有区别吗?

    分销商也可以横向扩展吗?

    documentation 建议使用单独的队列名称,但如果发送/发布系统应该关心接收系统是否横向扩展,这不是很麻烦吗?我认为,从发送方的角度来看,接收方的横向扩展应该是透明的。

    两个系统的订阅存储:MSMQ?订阅存储在哪里?在经销商那里?

  • 发射系统按比例缩放;吸收系统未缩放: 发射系统的多个节点可以发送到未缩放的吸收系统,就像上面的未缩放/未缩放场景一样。但是发射系统的多个节点不能(或不应该)发布到同一个吸收系统?要不然是啥?如何处理来自多个节点的发布

    两个系统的订阅存储:MSMQ?

  • 发射系统按比例缩放;吸收系统扩展:这只是发送/接收和发布/订阅模式的上述两种情况的组合吗?

    两个系统的订阅存储:MSMQ?

简而言之,对于上述四种情况下推荐的 NServiceBus 设置的概述可能会很好。

【问题讨论】:

  • 您是否仅限于 MSMQ? NServiceBus 也支持其他传输方式吗?
  • 不,我们不限于 MSMQ,但我喜欢 MSMQ 的分布式(即无代理)性质。此外,由于 MSMQ 带有 windows,它符合我们客户优先考虑标准 Microsoft 组件的愿望。不过,你会推荐其他东西吗?
  • 如果您想要基于标准 Microsoft 软件的另一个选项,可以使用 SQL Server 传输。这通过使用竞争消费者模式进行扩展,完全避免了对明确分发者的需求。
  • @UdiDahan - 我认为 NServiceBus 中的传输支持很差。令人惊讶的是,您不支持开箱即用的 MQ。在企业环境中,这是一个主要问题。
  • @Sean 我不确定在这里发表评论是否是我们进行此讨论的最佳场所,因此我创建了一个 GitHub 问题以使其更加可见和易于访问:github.com/Particular/NServiceBus/issues/2815

标签: .net msmq nservicebus


【解决方案1】:

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

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

在非缩放场景中,情况相同。假设ServiceAServiceB 部署到机器Machine1ServiceA 的逻辑端点地址和物理地址将是 ServiceA@Machine1。 ServiceB 的逻辑地址和物理地址为ServiceB@Machine1

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

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

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

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

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

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

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

还有MasterNode的概念。将其视为在同一物理进程中运行的 Distributor 和 Worker,以优化托管 Windows Failover Cluster 的机器上的资源使用。以上所有内容仍然适用于 MasterNode。

【讨论】:

  • 多么详尽的答案。谢谢!
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多