4.2 负载均衡器特性
现代负载均衡器的职责已经远超其最初的设计目标。本节将简要介绍负载均衡器常见的功能,帮助读者有个总体性的认识。
4.2.1 服务发现
服务发现是负载均衡器识别有哪些后端服务器的机制。不同的服务发现实现方式差异较大,以下是几种常见的实现方式:
- 静态配置文件:通过手动维护后端服务器配置实现基础的服务发现。
- DNS:将后端服务器的 IP 地址通过 SRV 记录或 A 记录注册到 DNS 服务器,客户端通过查询 DNS 记录获取后端服务器 IP 地址。
- 服务注册中心(如 Zookeeper、Etcd、Consul 等):后端服务器启动时向这些系统注册服务名称、地址、端口及健康检查信息。客户端通过查询 API 获取服务信息。这类方案通常内置健康检查机制,定期检测服务状态,并根据结果自动更新服务列表。
- Envoy 通用数据平面 API:提供标准化的数据平面接口(xDS 协议),实现跨平台和跨环境的服务发现(详见本书第八章 8.3 节)。
4.2.2 健康检查
健康检查用于评估后端服务器是否能够正常处理请求,目的是及时识别不可用的服务器并将流量重新分配。健康检查有两种手段:
- 主动健康检查:负载均衡器定期向后端发送健康探测,根据响应状态判断后端是否健康。如七层负载均衡器请求特定的健康检查路径(如 /health 或 /status),根据 HTTP 状态码判断后端服务健康状态。
- 被动健康检查:通过持续收集和分析请求、响应以及连接的状态信息,来判断后端服务器的状态。如在一段时间内发现某个后端出现多次连接失败、超时等异常,负载均衡器标记该后端为不健康。
4.2.3 粘性会话
对于某些特定应用,确保属于同一会话的请求被路由到相同的后端服务器至关重要。
会话的定义因应用而异,可能根据 HTTP cookies、客户端地址、请求头或其他相关属性来定义。大部分七层负载均衡器支持通过配置 HTTP cookies 或 IP 哈希来实现粘性会话(sticky session)。
需要注意的是,粘性会话涉及缓存和复杂的临时状态管理,实现粘性会话的设计通常很脆弱(赖于特定服务器、无法动态扩展、不可预测的负载分配问题等)。一旦处理会话的后端出现故障,整个服务可能都会受到影响。因此,设计依赖于该特性的系统时,需要格外谨慎。
4.2.4 TLS 卸载
TLS 卸载(TLS Termination)指将 TLS 的加密/解密、证书管理等操作,由负载均衡器进行统一收敛处理。这样的好处是:
- 减轻后端负载:后端服务器无需处理加密/解密操作,可以专注于业务逻辑处理。
- 减少运维负担:负载均衡器统一管理 SSL 证书的配置和更新,避免每个后端服务器单独管理证书。
- 提升请求效率:负载均衡器通常具有强大的硬件加速能力,经过了大量调优,处理 TLS 连接更有优势(参考本书第二章 2.5.2 节内容)。
4.2.5 安全和 DDoS 防御
负载均衡器可以实现 IP 黑/白名单、请求限速和鉴权等功能。根据 IP 的访问流量实现 QoS 控制,保证高优先级请求的响应时间,同时限制低优先级请求的频率,确保系统资源得到合理分配。
此外,通过稍后介绍的边缘代理的拓扑,即不同地理位置部署多个边缘代理,在靠近用户的位置分散流量,能减少延迟,对于防御 DDos 攻击尤其有效。
4.2.6 可观测性
从基本的统计信息(如流量、连接数和错误率)到与微服务架构集成的调用链追踪,不同层次的负载均衡器输出的可观测性数据各异:
- 四层负载均衡器的观测数据集中在连接、流量、错误、延迟等网络层面的分析。
- 七层负载均衡器的观测数据集中在 HTTP 请求、错误码、会话保持、路由分配等应用层面的分析。
需要注意的是,输出可观测性数据并非没有代价,负载均衡器需要进行额外处理来生成这些数据,但所带来的收益远超过那一点性能损失。
4.2.7 负载均衡
负载均衡解决的是:“给到一组健康的后端,选择谁来处理用户请求?”,也就是负载均衡器所采用的调度算法。
负载均衡调度算法是一个相对活跃的研究领域,从简单的随机选择,到更复杂的考虑各种延迟和后端负载状态的算法,笔者无法逐一展开,这里仅从功能和应用的角度简要介绍一些常见的负载均衡算法。
轮询均衡算法(Round-Robin):按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点是实现简单。轮询算法假设所有的服务器处理请求的能力都一样,调度器会将所有的请求平均分配给每个真实服务器。
最小连接均衡算法(Least-Connection):该算法中调度器需要记录各个服务器已建立连接的数量,然后把新的连接请求分配到当前连接数最小的服务器。
最小连接均衡算法特别适合于服务器处理时间不一致的场景。例如,当某些请求可能占用较长时间,而另一些请求很快就会完成时,最小连接算法可以有效避免某些服务器因处理大量复杂请求而过载。
一致性哈希均衡算法(Consistency Hash):将请求中的某些特征数据(例如 IP、MAC 或者更上层应用的某些信息)作为特征值来计算需要落在的节点。一致性哈希算法会保证同一个特征值的请求每一次都会落在相同的服务器上。
随机均衡算法(Random):此种负载均衡算法类似于轮询调度,不过在分配处理请求时是随机的过程。由概率论可以得知,随着客户端调用服务端的次数增多,其实际效果趋近于平均分配请求到服务端的每一台服务器,也就是达到轮询的效果。
以上算法假设的是所有服务器处理能力均相等,并不管服务器的负荷和响应速度。如果集群内各个服务器处理能力不一致呢?如服务器 A 每秒可处理 10 个请求,服务器 B 每秒可处理 100 个请求,不考虑服务器的处理能力的负载均衡算法,实际上是一种“伪均衡”算法。
考虑各个服务器的处理能力存在差异,负载均衡算法又有了对服务器“加权”的补充。
加权负载均衡算法增加了按权值高低分配的机制,权重较高的服务器处理更多的连接,从而保证集群内后端服务器的负荷整体上处于均衡状态。常用的加权负载均衡算法有加权轮询(Weighted Round Robin)、加权最小连接(Weighted Least-Connection)和加权随机(Weighted Random)等等,笔者就不再逐一介绍了。