扩展软件负载平衡器的典型方法是什么?

我经常在一堆应用程序服务器前看到带有SLB /反向代理的Web应用程序体系结构。

当到SLB的连接数量需要太多的资源用于单个 SLB才能有效处理时会发生什么? 对于具体而又过于顶级的例子,考虑200万个持久的HTTP连接。 显然, 单个 SLB无法处理这个问题。

推出 SLB的推荐configuration是什么?

创build一个LB /群集是典型的吗? 如果是这样,那么这组LB之间的客户端负载如何分布呢?

负载均衡器不容易被其他负载均衡器扩展,因为链路上固有的单个负载均衡器会维持连接。 也就是说,像LVS或HAProxy这样的平衡器在Gbps范围内具有荒谬的容量。 一旦你超越了单一负载平衡器(软件,硬件,无论)的function,那么你就需要进入其他技术,如循环DNS。

好的,已经有了一个可以接受的答案,但是还有一些东西需要补充。 扩展负载平衡器层的最常见的“经典”方法是 (没有特定的顺序):

  • DNS Round Robin来公布该域的多个IP地址。 对于每个IP地址,实现一个高可用性服务器对(两台服务器协同工作,始终保持一个IP地址正常工作)。每个IP对应一个负载均衡器集群,可以使用装置或具有负载平衡软件的服务器。 通过根据需要添加更多负载平衡器对来进行横向扩展。

  • 路由或防火墙调整将负载分散到多个负载均衡器。 让前端路由器或前端防火墙通过散列源IP地址 ,具有到负载均衡器的多个等成本路由等,将传入连接分散到多个IP地址(每个代表一个负载均衡器对)。

  • 在一层HTTP级负载均衡器之前的一层IP级负载均衡器 。 IP层负载均衡可以在ASIC /硅片上实现,并且对于某些事情可以快速恶化。 因此,单个IP负载平衡器对可以经常与多个HTTP / HTTPS级别的负载平衡器保持同步,并提供数千兆位的性能水平,同时保持架构的优良和简单。

要完成上述不同的方式,需要很长的回答。 但总的来说, 扩展负载平衡器层并不难,扩展应用服务器层,尤其是数据库层则更加困难。

无论您select设备外形(F5,思科,A10)还是通用服务器(Windows / Linux +软件),都不至于如此。 扩展负载均衡器层的主要考虑因素是:

  • 国家充分与无国籍。 你绝对需要粘稠的会议,或者你可以没有生活吗? 不保持状态使一切变得简单。
  • “硬件”(ASIC)与“软件” (通用服务器)之间的负载平衡。 各有其优点和缺点,请参阅上面链接的HAProxy概述文档。
  • L3 / 4(IP / TCP / IP)负载平衡与L7(HTTP)负载平衡。 正反两方面,HAProxy文档提供了一个很好的概述。
  • SSL终止 ,在networking节点或负载均衡器上。

一般来说,在你的网站变得非常庞大之前,你不需要担心这个问题 – 一台使用fx nginx的现代服务器每秒将处理数以万计的普通HTTP请求。 所以不要做过早的优化,在你不得不处理之前。

扩展HTTP负载平衡层的关键是首先添加另一层较低层(IP或TCP)的负载平衡。 这个层可以完全用开源软件构build,但是如果你有现代化的路由器,你会得到更好的结果。

应该使用诸如源/目的地IP和TCP端口之类的头部对stream (TCP会话)进行散列 ,以决定它们前往哪个前端。 你还需要一个机制来确保当前端死亡时,它不会被使用。

有各种各样的策略,我将概述一些我在用于数百万用户的网站上的制作中使用的一对,所以你可以得到这个想法。 详细解释所有内容都太长了,但是我希望这个答案能给你足够的信息/指示。 为了实现这些解决scheme,您将需要一个对networking非常了解的人。

无可否认,我在这里描述的要比其他答案中描述的要难得多,但是如果您有一个高stream量的网站,其可扩展性问题和可用性要求超过99.9%,那么这确实是最先进的技术。 。 假如你已经拥有一个networking工程师,那么你可以在负载平衡器设备上安装和运行(在capex和opex中),而且可以在几乎没有额外成本的情况下进一步扩展(相对于购买新的,甚至更多昂贵的电器,当你超出你现有的模型)。

第一个策略:用防火墙

据推测,你有一个连接你的ISP上行链路的路由器。 您的ISP提供2个链接(主动/被动,使用VRRP)。 在您的路由器上,您也可以使用VRRP,并将stream向公共networking的stream量路由到防火墙。 防火墙(下面的FW 1FW 2 )也是主动/被动的,将过滤stream量并将每个stream量发送到健康的前端服务器(您的HTTP负载均衡器,下面的FE 1FE 2 )。

       + -------------- + + -------------- +
       |  ISP路由器A |  |  ISP路由器B |
       + -------------- + + -------------- +
              |  |
            ==#======================#==(公网)
              |  |
       + --------------- + + --------------- +
       | 你的路由器A |  | 你的路由器B |
       + --------------- + + --------------- +
              |  |
            ==#=====#==========#=====#==(RFC 1918专用networking)
              |  |  |  |
        + ------ + + ------ + + ------ + + ------ +
        |  FW 1 |  |  FE 1 |  |  FE 2 |  |  FW 2 |
        + ------ + + ------ + + ------ + + ------ +

目标是让stream程如下所示:

  1. ISP将通往您的IP的stream量路由到您的活动路由器。
  2. 您的路由器将stream量路由到使用RFC 1918地址的VIP。 这个VIP属于主动防火墙,非常像VRRP。 如果您使用OpenBSD来满足您的防火墙需求,那么您可以使用CARP ,这是一个无需替代VRRP / HSRP的专利。
  3. 你的防火墙应用filter(例如“只允许80 / tcp和443 / tcp去这个特定的IP地址”)。
  4. 您的防火墙还充当路由器,并将数据包转发到健康的前端。
  5. 你的前端终止了TCP连接。

现在魔法发生在第四步和第五步,所以让我们更详细地看看他们做了什么。

您的防火墙知道前端列表( FE 1FE 2 ),并根据stream程的特定方面(例如通过散列源IP和端口以及其他头部)来select其中的一个。 但是,它也需要确保它将stream量转发到健康的前端,否则会导致黑客stream量。 如果你使用OpenBSD,你可以使用relayd 。 什么relayd很简单:它健康检查所有的前端(例如通过发送一个探测HTTP请求),每当前端健康,它将它添加到防火墙用来select数据包的下一跳的表给定stream量。 如果前端运行状况检查失败,则将其从表中删除,并且不再发送数据包。 将数据包转发到前端时,防火墙所做的就是将数据包的目标MAC地址交换为所选前端的MAC地址。

在步骤5中,来自用户的数据包被负载均衡器(无论是Varnish,nginx还是其他)收到。 在这一点上,数据包仍然是注定你的公共IP地址,所以你需要在回环接口别名你的VIP(s)。 这被称为DSR (直接服务器返回),因为你的前端终止了TCP连接,而在两者之间的防火墙只能看到单工stream量(只有传入的数据包)。 您的路由器会将传出的数据包直接路由回ISP的路由器。 这对于HTTPstream量来说特别有用,因为请求往往比响应要小,有时候非常重要。 需要说明的是:这不是一个特定于OpenBSD的东西,而且广泛应用于高stream量的网站。

陷阱:

  • 最终用户将直接连接到您的前端服务器,因为您使用DSR。 也许情况已经如此,但是如果不是的话,你需要确保它们得到充分的保护。
  • 如果您使用OpenBSD,请注意内核是单线程的,因此单个CPU内核的性能会限制防火墙的吞吐量。 这可能是一个问题,取决于您所看到的NIC的types和数据包的速率。 有办法解决这个问题(更多在这下面)。

第二个策略:没有防火墙

这个策略更有效但更难设置,因为它更多地取决于你所拥有的路由器的细节。 这个想法是绕过上面的防火墙,让路由器完成防火墙所做的所有工作。

您需要支持每端口L3 / L4 ACL, BGP和ECMP以及策略路由 (PBR)的路由器 。 只有高端路由器支持这些function,并且他们通常会使用BGP的额外许可费用。 这通常比硬件负载平衡器还便宜,而且容易扩展。 关于这些高端路由器的好处是,它们往往是线速的(例如,即使是在10GbE接口上,它们也总能最大限度地发挥链路的作用),因为所有的决策都是由ASIC完成的。

在您有ISP上行链路的端口上应用曾经在防火墙上的ACL(例如“只允许80 / tcp和443 / tcp转到这个特定的IP地址”)。 然后让你的每个前端与你的路由器保持一个BGP会话。 你可以使用优秀的OpenBGPD (如果你的前端在OpenBSD上)或者Quagga 。 您的路由器将ECMPstream量转移到健康的前端(因为他们正在维护他们的BGP会话)。 路由器也将使用PBR适当地路由stream量。

改进

  • 使用防火墙对解决scheme,如果可以在防火墙之间同步TCP状态,那么很好,这样当一个防火墙发生故障时,所有事情都能顺利地转移到另一个防火墙。 你可以用pfsync来实现这个function。
    • 请记住, pfsync通常会使防火墙上的数据包速率加倍。
    • HTTP是一种无状态协议,因此如果在防火墙故障转移期间重置所有连接,则不是世界末日,因为您不使用pfsync
  • 如果您超出了单个防火墙,则可以在路由器上使用ECMP将stream量路由到多对防火墙。
  • 如果你使用多对防火墙,那么你也可以把它们全部激活/激活。 你可以通过让防火墙和路由器保持BGP会话来实现这一点,就像前端需要在没有防火墙的第二个devise中维护一个一样。

示例relaydconfiguration

另请参阅https://calomel.org/relayd.html上的 HOWTO

 vip =“1.2.3.4”#你的公共IP地址
                #(你可以有多个,但不需要)
 FE1 = “10.1.2.101”
 FE2 = “10.1.2.102”
的Fe3 = “10.1.2.103”
 fe4 =“10.1.2.104”#你可以有任意数量的前端。
 int_if = “EM0”
表<fe> {$ fe1重试2,$ fe2重试2,$ fe3重试2,$ fe4重试2}
表<fallback> {127.0.0.1}

redirectwebtraffic {
        听$ $端口80
        会话超时60
        路由到<fe>检查http“/healthcheck.html”摘要“(healthcheck.html的sha1sum)”接口$ int_if
 }

就我个人而言,我会select比较简单,可configuration性较差的硬件负载均衡器,比如思科的ACE / ASA,Foundry ServerIron,甚至可能是宙斯ZXTM(一种devise为负载很重的SW LB)。

或许不是一直保持这么多开放的连接来发送回复,而是以这样一种方式编写你的应用程序,以便客户端可以定期轮询你的服务器。

无论你在做什么,实际上需要毫秒级的响应还是客户端可以等待15/20秒,直到下一个轮询周期?

一个典型的方法是创build一个足够大的集群来处理所需的负载,并使用一个可以进行确定性负载平衡的SLB(对于持续连接)。

像CARP这样的东西使用请求IP的哈希来确定哪个后端Web服务器将处理请求,这应该是确定性的,但是如果在负载平衡器之前有防火墙或者NAT,那么它不是非常有用。
如果您在Linux上运行,您也可能会发现像IPVS这样有用的东西。