首页 > 解决方案 > 如何在 .NET 中对服务的工作负载进行负载平衡

问题描述

我正在考虑使用面向服务的体系结构 (SOA) 构建应用程序。

这种架构不像微服务解决方案那样复杂和混乱(我认为),但我面临着类似的设计问题。想象一下,我有 ServiceA 类型的服务,它们将工作发送到 ServiceB 类型的服务。我想,如果我使用队列,那么负载平衡将不会成为问题(因为消费者将从队列中获取他们可以处理的内容)。但是队列往往会在代码中产生一些不良的异步性,需要额外的努力来修复。所以,我更倾向于在服务之间使用 HTTP 调用,利用async/awaitC# 的高效和惊人的特性。但这会在共享工作负载和检测饱和或失效的服务方面产生问题。

所以我的问题是:

  1. 是否有一个队列支持某种async/await功能,并且其功能类似于 HTTP 调用,它在您需要的地方返回结果,而不是在无法继续原始执行流程的某个回调中?
  2. 使用 HTTP 时,如何对服务之间的流量进行负载平衡并检测不适合新分配的节点?我的意思是,我可能可以自己从头开始设计一些东西,但现在应该有一些标准的方法或库或框架来做到这一点。我在网上找到的最好的是this,但它是为微服务构建的,所以我不确定我是否可以毫无问题或过度使用它。

更新: 我现在发现了这个问题,它也要求等待队列:基于任务的等待队列 ......并且还发现了 Kubernetes、Marathon 等。

标签: c#.netarchitectureload-balancingsoa

解决方案


关于您的第一个问题,NServiceBus 是 .NET 的一个商业框架,它抽象了消息传输并在其之上添加了许多功能,它具有您正在寻找的确切功能。他们实际上称之为“回调”,用法如下:

假设您有要发送到后端服务的消息和您期望返回的响应,您可以在 ServiceA 中执行以下操作:

var message = new Message();
var response = await endpoint.Request<ResponseMessage>(message);
log.Info($"Callback received with response:{response.Result}");

其中端点是允许您发送消息和接收消息的 NServiceBus 工件。

这个简单的语法将做的是将 Message 放入队列并等待(异步),直到消息已由后端服务处理并已回复。响应是队列中响应类型的消息。

在 ServiceB 中,您将执行以下操作:

public class Handler : IHandleMessages<Message>
{
  public Task Handle(Message message, IMessageHandlerContext context)
  {
    var responseMessage = new ResponseMessage
    {
        Result = "TheResult"
    };
    return context.Reply(responseMessage);
  }
}

这允许您让多个 ServiceA 节点向多个 ServiceB 节点发送消息(在单个队列中竞争消费者)。NServiceBus 负责将每个给定消息的响应路由到正确的 ServerA。

请注意,这样做的缺点是如果 ServerA 在等待响应时出现故障,您将永远不会收到响应。因此,不建议在大多数情况下使用此模式。

关于您的问题 2,我会说负载均衡器可以完成这项工作。对于更复杂的场景,您可以查看Service Fabric


推荐阅读