【问题标题】:In ASP.NET, is there a way to write a custom Load Balancer?在 ASP.NET 中,有没有办法编写自定义负载均衡器?
【发布时间】:2012-01-30 21:48:00
【问题描述】:

我一直致力于通过 WCF 实现 (1) 个服务器、(n) 个辅助角色服务器设置。一台服务器处理请求,通过 WCF 将工作传递给可用的工作角色,后者处理请求,并将数据传递回服务器。对于我能够处理的事情来说,这有点太复杂了。我正在尝试简化解决方案,并认为我可以通过创建 (n) 个服务器来删除 WCF 组件,每个服务器都能够处理工作角色服务和 Web 服务器角色。假设每个工作服务器只能扮演 (1) 个工作角色。

这样,当一个请求进来时,一些循环式处理程序会选择一个可用的服务器并将 HTTP 请求转发到该服务器/worker。该服务器/工作者完成工作,并将数据直接返回给请求者。

这是一种可行的方法吗?我意识到对于一些高级开发人员来说,WCF 解决方案不会造成任何问题。我想问是否有一种更简单、更具黑客风格的方法,可以让我以我有限的能力创建一个服务器解决方案,然后复制和负载平衡该解决方案的多个版本?

任何建议都非常感谢!

【问题讨论】:

  • 哈!谢谢你。对不起我糟糕的西班牙语。
  • @ICarus:你的评论没有增加任何内容,而且是冒犯和粗鲁的。获得生命。
  • @kprobst 我不是故意粗鲁的。我试图推广我参与的 spanish.stackexchange.com。如果我在这里冒犯了任何人,特别是 Hairgami_Master,请接受我的道歉。
  • @Icarus:明白。你的评论只是被认为是敌对的。我也向你道歉。
  • 不用担心@Icarus。我喜欢西班牙语——希望我能说得很好!

标签: asp.net wcf load-balancing


【解决方案1】:

您所描述的正是负载均衡器的用途——它们试图在可用服务器池中分配传入请求。

许多托管公司提供涉及多台服务器的托管计划,您可以选择对传入请求进行负载平衡。

例如:Rackspace 提供负载平衡作为其某些托管计划的可选功能。

如果您在 Microsoft 的 Azure 云中托管具有多个 Web 角色实例的站点,您的站点会自动为您进行负载平衡。您还可以构建您的站点,使其在多个地理区域实现动态负载平衡,从而将来自亚洲(例如亚洲)的请求路由到亚洲的数据中心,从而减少延迟和数据中心内的带宽。

另外,考虑在前端网站和后端批处理/密集型工作负载处理之间引入队列/消息总线。这样您就可以独立扩展系统的前端和后端。

如上所述,不要过度设计您的解决方案 - 专注于构建一个稳定、稳固、可靠、高效的系统,然后监控和衡量其性能并在适当的情况下对其进行调整。否则,您可能会花费宝贵的时间和精力来实施对网站或用户没有实际好处的功能/调整!


根据 OP 的 cmets 更新 2012-01-31:

如果您想让您的工作角色一次执行一项任务,并且只在他们不再忙时才返回执行另一项工作,我建议您颠倒您的架构:

与其让某些前端服务器尝试找出哪些工作人员“忙碌”并相应地分配工作,不如考虑让您的前端服务器将传入消息排队到“传入”队列中。

工人从前端“拉”一个新的工作项,执行任何需要的工作,然后通知前端工作完成并请求另一个工作项。

这种方法的美妙之处在于它可以以线性方式扩展,并且具有很高的弹性。

当工作人员“拉”新工作项时,前端会为消息添加时间戳并将其移动到辅助“待处理”队列。工人在完成工作项时通知前端;前端将已完成的项目移动到“已完成”队列(如果不关心,则将其删除)。

然后前端可以对“待处理”队列运行定期扫描,查找等待时间过长的消息,如果这些消息等待时间过长,可以将这些消息返回到“传入”队列。

队列可以很有趣:) 但是,构建这样一个队列系统可能很复杂,并且使其真正可靠可能既耗时又昂贵。

幸运的是,您可以利用一些非常熟练的消息总线实现,这些实现将为您提供实现这一目标所需的 90%!我最喜欢的是 Microsoft 基于云的 Azure Message Bus,它为您提供了一个非常适合您的场景的非常坚固的持久消息传递、发布订阅和队列基础架构。

HTH。

【讨论】:

  • 谢谢 Richard- 我正在处理一个非常非常特殊的边缘情况,需要假装每台服务器都是单例,一次只能处理一个请求。我正在尝试为这个独特的案例提出一个负载平衡解决方案——如果你能想到任何可能有帮助的东西,我会全力以赴。干杯!
  • 用可能适合您需求的替代方法更新了我的答案。
【解决方案2】:

我不会推荐这个。起初,平衡对于大多数开发人员来说似乎很简单(“嘿,我只会跟踪每个请求并将下一个请求转发到排队的下一个服务器,等等”),但实际上如果它不是完全微不足道的话,它就会很复杂。您需要考虑维护每台服务器的负载配额、处理出现故障的服务器等。

如果您已经在运行 Server 2008,那么使用操作系统的 NLB 功能而不是自己开发可能更便宜、更容易(而且性能更高)。例如,This 是一个很好的设置 NLB 集群的演练。

当然,最终方法取决于您,但我认为为工作使用正确的工具始终是一个好主意。如果您已经将其融入操作系统,那么在 WCF 服务中重新发明循环 IP 集群似乎是在浪费时间。

祝你好运:)

【讨论】:

  • 谢谢@kprobst!在这个特殊的边缘情况下,我需要假装每个服务器都是单例,一次只能服务一个客户端。如果任何特定服务器忙,负载平衡器将需要寻找另一台不忙的服务器。无需担心 ASP 会话或状态。这会让你有什么不同的想法吗?
  • @Hairgami_Master 但是您将如何确定特定服务器是否繁忙?当您尝试将其扩展到现实世界的场景时,这种复杂性会很快变得非常老旧。就像我说的,如果您的平衡需求相对简单,那么我认为您的方法会奏效,但这不是我会选择的长期解决方案。
  • 我希望有一种简单的方法可以使 IHttpHandler 成为单例......我可以轻松检测到并继续前进并尝试下一个服务器,如果它很忙。也许没有办法做到这一点。非常感谢!
【解决方案3】:

我建议您采用完全不同的方法。

也就是说,不是将作业推送到特定服务器,而是让场中的每个服务器轮询可用的作业。

这样做的主要原因是您要求每台服务器“一次只能为 1 个客户端提供服务”。


所以,设置一下:

  1. 一个请求进来了。
  2. 请求记录到工作表中
  3. 您的一个工作服务器请求下一个作业。
  4. 已分配给该服务器。
  5. 工作完成后,服务器会将其标记为已完成。

现在,这为您提供了一些选择。首先,重新分配是微不足道的......只需清除当前分配作业的服务器即可。您可能有一个监视器在监视此表,如果某项工作“花费太长时间”,那么您可以简单地允许其他服务器来获取它。

此外,您可以随意添加或删除工作服务器,而无需通知某种类型的控制服务器机器现在在线或离线。


为了更加稳健,您可以让每个工作服务器检查您的数据库,以表明它已准备好工作。然后服务器会每隔几秒检查一次,看看是否有任何分配。

SQL 作业可能会经常执行以分配工作。如果机器处理时间过长,它还可能负责重新分配。

【讨论】:

  • 嗨克里斯-谢谢你的建议。我目前正在通过 Amazon SQS 做这样的事情。虽然它工作正常,但速度不够快,我正在尝试提出一个解决方案,删除所有对 SQS 的写入、轮询消息、工作、工作、在某处写工作结果等。我可以让一台服务器如此轻松地做到这一点,似乎如果我只是复制那台服务器,并想出一种跨多台服务器进行负载平衡的智能方法,这将是一个简单的解决方案。 :)
  • @Hairgami_Master:您的主要问题是如何处理不可避免的机器故障。随着您的扩展,机器将突然出现和退出可用性。根据实施情况,轮询计算机列表的可用性实际上可能需要更长,而不仅仅是让它们请求它。
  • 我只是在想同样的事情。谢谢。
猜你喜欢
  • 2016-07-17
  • 1970-01-01
  • 2016-03-08
  • 2018-09-17
  • 2018-06-04
  • 2021-12-07
  • 1970-01-01
  • 2018-04-29
  • 2018-11-16
相关资源
最近更新 更多