负载均衡入门:基本原理
简介
在当今瞬息万变、以应用为中心的市场中,组织面临着越来越大的压力,需要快速、可靠且安全地交付客户所期望的信息、服务和体验。负载均衡、加密、加速和安全等关键网络与应用功能可通过应用交付控制器(ADC)提供。ADC是作为物理服务器代理运行的物理或虚拟设备。随着应用数量激增,加之持续集成和持续部署(CI/CD)的严格周期给组织带来的压力,预计到2020年,ADC市场规模将达到每年29亿美元,这并不令人意外。1
不过,在展望未来之前,我们先回顾一下发展历程。基于网络的负载均衡是ADC运行的必要基础。20世纪90年代中期,首批负载均衡硬件设备开始通过在服务器和网络之间分配工作负载,帮助组织扩展应用。这些早期设备不依赖特定应用,并部署在应用服务器之外,因此可以使用简单直接的网络技术进行负载均衡。具体而言,这些设备会向外部提供一个“虚拟IP地址”。当用户尝试连接时,设备会执行双向网络地址转换(NAT),将连接转发到最合适的真实服务器。
然而,随着虚拟化和云计算的兴起,新一代负载均衡ADC应运而生。这些ADC以软件形式提供虚拟版本,旨在运行于虚拟机监控程序之上。如今,虚拟设备可提供应用服务,其功能范围与运行在专用硬件上的设备相当。此外,这些虚拟版本大幅降低了在虚拟、云和混合环境之间迁移应用服务的复杂性,使组织能够在私有云或公有云环境中快速、轻松地启动应用服务。
数据中心领域的新趋势是容器化。这是一种应用虚拟化方法,有助于部署和运行分布式应用。容器化会隔离应用,并将其限制在共享操作系统上边界清晰的内存空间中。与构建虚拟设备相比,这不仅能简化应用的开发和部署,还能缩短所需时间。由于可移植性和性能显著提升,容器化可以帮助企业提高可扩展性和敏捷性。未来,容器架构还可以帮助组织更充分地利用不同的云环境。
如今的ADC由早期的负载均衡器经过服务虚拟化演进而来。现在,借助纯软件虚拟版本,ADC不仅可以提高可用性,还能帮助组织交付业务所需的可扩展、高性能且安全的应用。不过归根结底,如果没有负载均衡技术这一坚实基础,所有这些虚拟化应用服务、共享基础设施部署和智能路由功能都无法实现。
为了了解企业如何更好地应对瞬息万变的市场所带来的复杂挑战,让我们从应用交付的基础入手:负载均衡入门。

基础知识:术语
开始之前,先来了解一下负载均衡的基本术语。如果大家使用相同的词汇,理解起来会更容易;遗憾的是,各家负载均衡设备(以及相应的ADC)供应商似乎都采用不同的术语。不过,稍加说明,就能理清这些概念。
节点、主机、成员和服务器
大多数负载均衡ADC都使用节点、主机、成员或服务器等概念;有些ADC同时使用这四个概念,但各自含义不同。这些术语主要用于表达两个基本概念。其中一个概念通常称为节点或服务器,指接收ADC流量的物理服务器或虚拟服务器本身。它等同于物理服务器的IP地址;如果没有负载均衡器,服务器名称(例如www.example.com)将解析到该IP地址。本文后续将这一概念称为主机。
第二个概念用“成员”一词表示(遗憾的是,一些制造商也将其称为节点)。成员的定义通常比主机更具体,因为它还包括实际接收流量的应用所使用的TCP端口。例如,名为www.example.com的主机可能解析为地址172.16.1.10,该地址代表主机;该主机上可能有一个应用(Web服务器)在TCP端口80上运行,因此成员地址为172.16.1.10:80。简而言之,成员的定义既包括应用端口,也包括物理或虚拟服务器的IP地址。本文后续将这一概念称为服务。
为什么要如此复杂?因为区分服务器与其上运行的应用服务后,无论是在数据中心还是云端,负载均衡器都可以分别与各个应用交互,而不是与底层硬件或虚拟机监控程序交互。一台主机(172.16.1.10)可能提供多种服务(HTTP、FTP、DNS等)。通过唯一定义每个应用(例如172.16.1.10:80、172.16.1.10:21和172.16.1.10:53),ADC可以基于服务而非主机,分别应用负载均衡和运行状况监控(这一概念将在后文讨论)。
请注意,大多数基于负载均衡的技术会使用一个术语表示主机(即物理服务器),并使用另一个术语表示主机上提供的服务。在本例中,这两个术语分别是“主机”和“服务”。
池、集群和服务器场
负载均衡可帮助组织将入站应用流量分配到多个后端目标,包括部署在公有云或私有云中的目标。因此,需要使用后端目标集合这一概念。本文将此类集合称为集群(也称为池或场),即任意数量主机上提供的同类服务的集合。例如,所有提供公司网页的服务可归入名为“公司网页”的集群,所有提供电子商务服务的服务可归入名为“电子商务”的集群。
虚拟服务器
虚拟服务器是实际服务器(物理服务器、虚拟服务器或容器)的代理。虚拟服务器与虚拟IP地址结合,构成面向外部的应用端点。
整合所有内容
了解这些术语后,我们就掌握了负载均衡的基础知识。负载均衡ADC向外部提供虚拟服务器。每台虚拟服务器都指向一个服务集群,这些服务位于一台或多台物理主机上。

虽然图2可能无法代表任何实际部署,但它确实提供了一个基本结构,可用于进一步探讨负载均衡和应用交付流程。
负载均衡的工作原理
明确这些常用术语后,下面通过一个简单的事务流程,了解应用如何交付给客户。如图所示,负载均衡ADC通常以内联方式部署在客户端与提供客户端所需服务的主机之间。与应用交付中的大多数情况一样,这种部署位置并非硬性规定,而是适用于各类部署的常见良好实践。另假设ADC已配置一个虚拟服务器,该服务器指向由两个服务点组成的集群。在此部署场景中,主机通常会配置一条指向负载均衡器的返回路由,以便返回流量在发回客户端的途中经由负载均衡器处理。
基本的应用交付事务流程如下:
- 客户端尝试连接到该服务。
- ADC接受连接,并在确定应由哪台主机接收该连接后,更改目标IP(也可能更改端口),使其与所选主机的服务相匹配(请注意,客户端的源IP不会被更改)。
- 主机接受连接,并通过其默认路由ADC向原始源(即客户端)返回响应。
- ADC拦截来自主机的返回数据包,将源IP(以及可能的端口)更改为与虚拟服务器的IP和端口一致,然后将数据包转发回客户端。
- 客户端收到返回数据包,并认为该数据包来自虚拟服务器,然后继续处理。

这个示例非常简单,比较容易理解,但有几个关键要素需要注意。首先,从客户端的角度来看,它向虚拟服务器发送数据包,虚拟服务器作出响应,过程很简单。其次,系统会执行NAT。在此过程中,ADC会将客户端发送的数据包中的目标IP(即虚拟服务器的IP)替换为其选择用于对请求进行负载均衡的主机的目标IP。第三,此过程中的这一步使NAT成为“双向”转换。从主机返回的数据包会以该主机的IP作为源IP;如果不更改此地址,而只是将数据包转发给客户端,客户端就会收到一个并非来自其请求对象的数据包,因此会直接将其丢弃。负载均衡器则会记住该连接,并重写数据包,将源IP改为虚拟服务器的IP,从而解决这一问题。
应用交付决策
通常到这一步,会出现两个问题:负载均衡ADC如何决定将连接发送到哪台主机?如果选定的主机无法正常工作,又会怎样?
先来讨论第二个问题。如果选定的主机无法正常工作,会发生什么情况?简单来说,该主机不会响应客户端请求,连接尝试最终会超时并失败。这显然不是理想情况,因为无法确保高可用性。因此,大多数负载均衡技术都具备一定程度的运行状况监控功能,以便在尝试向主机发送连接之前,确定该主机是否确实可用。
健康监控分为多个级别,粒度和关注重点逐级提高。基础监控器只需对主机本身执行ping操作。如果主机未响应ping,则可以合理推断,该主机上定义的所有服务可能均已停止运行,应从可用服务集群中移除。但即使主机响应了ping,也不一定意味着服务本身运行正常。因此,大多数设备都能执行某种形式的“服务ping”,从建立简单的TCP连接,到通过脚本化或智能交互与应用进行通信。这些更高级别的健康监控器不仅能更可靠地判断实际服务(而非主机)是否可用,还能让负载均衡器区分同一主机上的多个服务。负载均衡器能够识别:即使某项服务不可用,同一主机上的其他服务仍可能正常运行,因此仍应将其视为用户流量的有效目标。
这又回到了最初的问题:ADC如何决定将连接请求发送到哪台主机?每个虚拟服务器都有一个专用的服务集群,其中列出了提供该服务的主机,构成可选主机列表。此外,健康监控会调整该列表,生成提供指定服务且“当前可用”的主机列表。ADC正是从调整后的列表中选择接收新连接的主机。具体选择哪台主机,取决于与该集群关联的负载均衡算法。这些算法包括最少连接、动态比率和简单轮询。采用简单轮询时,负载均衡器从列表顶部开始依次向下,将每个新连接分配给下一台主机;到达列表底部后,再从顶部重新开始。这种方法简单且结果很容易预测,但它假定所有连接在后端主机上产生的负载和持续时间都相近,而实际情况并非总是如此。更高级的算法会利用当前连接数、主机利用率,甚至主机现有流量的实际响应时间等信息,从集群的可用服务中选择最合适的主机。
足够先进的应用交付系统还能够综合运用运行状况监控信息和负载均衡算法,将服务依赖关系纳入考量。这主要适用于单台主机提供多项服务,且必须由所有这些服务共同完成用户请求的情况。在这种情况下,不应将用户请求发送到仅有部分服务正常运行的主机。换言之,如果主机上的一项服务发生故障,还应将该主机上的其他服务从可用服务的集群列表中移除。随着HTML和脚本使服务日益差异化,此功能也变得越来越重要。
要不要进行负载均衡?
负载均衡解决方案并不只是当客户端发起事务请求时选择可用服务。连接建立后,ADC必须持续判断是否应对该用户的后续流量进行负载均衡。处理经过负载均衡的后续流量时,通常需要解决两个具体问题:连接维护和持久性。
连接维护
如果用户尝试使用不会立即关闭的长连接TCP连接(端口21:FTP、端口23:Telnet或其他连接),负载均衡器必须确保通过该连接传输的多个数据包不会被负载均衡到其他可用的服务主机。这就是连接维护,需要具备两项关键能力。第一,能够跟踪打开的连接及其所属的主机服务。第二,负载均衡器必须能够持续监控该连接,以便在连接关闭时更新连接表。对于大多数ADC而言,这些都是相当标准的功能。
持久性
不过,越来越常见的情况是,客户端使用多个短时TCP连接(例如端口80:HTTP)来完成一项任务。在某些情况下(如常规网页浏览),每个新请求可以发送到任意后端服务主机,并不会造成影响;但在许多场景中(如XML、电子商务等),同一用户的多个连接必须发送到同一后端服务主机,而不能进行负载均衡,这一点至关重要。这一概念称为持久性,也称为服务器亲和性。
具体可采用多种方法,具体取决于协议和预期结果。例如,在现代HTTP事务中,服务器可以指定“keep-alive”连接,将多个短期连接转变为单个长期连接,并像处理其他长期连接一样进行处理。不过,这只能略微缓解问题,主要是因为随着Web和移动服务的使用日益增加,让所有连接保持打开状态超过必要时长会给整个系统的资源带来压力。因此,如今许多组织为了提高可扩展性和可移植性,正逐步转向构建依赖API的无状态应用。这基本意味着服务器会丢弃所有会话信息,以减轻资源负载。在这种情况下,状态通过传递会话ID以及持久性机制来维持。
最基本的持久性形式之一是源地址亲和性,即记录传入请求的源IP地址及其经负载均衡后所分配到的服务主机,并将后续所有事务都发送到同一主机。实现这种持久性有两种方式:使用SSL会话ID或Cookie。SSL持久性使用SSL会话ID跟踪SSL会话。这意味着,即使客户端的IP地址发生变化,负载均衡器仍可根据会话ID识别该持久会话。基于Cookie的持久性可以在客户端计算机上写入Cookie,以唯一标识会话;后续请求会引用该Cookie,从而将连接发送到正确的服务器。
如今,ADC的智能功能支持组织打开数据包,并针对其中几乎任何内容创建持久性表。这样,组织便可使用用户名等唯一信息来保持会话持久性。不过,组织必须确保每个请求都包含此类可识别的客户端信息,否则,不含这些信息的数据包将无法保持会话持久性,而是会再次进行负载均衡,这很可能导致应用中断。
结论
最初,负载均衡主要用于在整个网络中分配工作负载,并确保应用和服务的可用性。随着技术发展,负载均衡器逐渐演变为应用交付平台,确保组织的关键应用具备高可用性和安全性。虽然基础负载均衡仍是应用交付的基础,但现代ADC可提供更多增强功能。
企业已经认识到,能够访问应用并不意味着应用可用,而不可用的应用会浪费部署该应用的组织的时间和资金。现代ADC正是为此而生,它支持组织将SSL/TLS卸载、缓存、压缩、速率整形、入侵检测、应用防火墙乃至远程访问等基于网络的服务整合到一个战略节点,并在所有应用服务和主机之间共享和复用,从而构建虚拟化应用交付网络。这有助于网络、应用和运维团队更好地满足企业对缩短交付周期和提高可扩展性的需求,同时不牺牲安全性。
如需进一步了解高级应用交付的工作原理及ADC的未来发展,请阅读《应用交付控制器的演进》和《超越传统负载均衡》。
1 http://www.strategyr.com/MarketResearch/Application_Delivery_Controllers_ADC_Market_Trends.asp
发布于2017年5月10日
