【问题标题】:How to load-balance the workload of a service in .NET如何在 .NET 中对服务的工作负载进行负载平衡
【发布时间】:2018-10-12 08:35:57
【问题描述】:

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

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

所以我的问题是:

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

更新: 我现在发现了这个问题,它也要求等待队列:awaitable Task based queue ...并且还发现了 Kubernetes、Marathon 等。

【问题讨论】:

  • 所有队列和调用都可以是异步的。这只是网络IO。问题是图书馆是否支持它,但很可能支持。另一个问题是你是否真的受限于线程。如果不是,异步 IO 的优势为零,但开发和性能成本。
  • 如果您将每个服务置于负载均衡器之后,您只需调用 LB 端点。如果每个服务在服务过载的情况下拒绝额外的客户端请求,那么调用者可以很容易地检测到不可用的服务。短暂的超时也很有用。
  • 我没有在队列顶部实现请求/回复的经验,但是您可以编写自己的异步代码来隐藏机制并使其像await CallServiceByQueueAsync(...) 一样简单。也就是说,如果您需要同步结果,队列似乎毫无意义。对负载平衡器的 HTTP 调用似乎更容易做到。
  • @usr 是的。我主要是在寻找队列的请求/回复功能。一个优点是,使用负载均衡器时,您必须在拒绝回复时回退到其他服务,而使用队列时,服务会在可以处理工作时接手工作。我觉得这可以通过减少调用次数或降低复杂性来节省时间,因为您没有负载均衡器来如此频繁地跟踪每个服务的状态。但似乎像 Kubernetes 这样的现有解决方案可以解决这个问题。不过,设计一个等待队列会很有趣。

标签: c# .net architecture load-balancing soa


【解决方案1】:

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

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

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

endpoint 是一个 NServiceBus 工件,允许您发送和接收消息。

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

在 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。

【讨论】:

  • 非常感谢! NServiceBus 看起来很有前途和有趣! :)
  • 是的。他们的支持和讨论组是一流的
猜你喜欢
  • 2018-10-14
  • 1970-01-01
  • 2012-09-29
  • 2012-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
相关资源
最近更新 更多