为什么需要

单台服务器的处理能力有上限。当流量增长,有两个方向:

  • 纵向扩展(Scale Up):换更强的机器(更强的 CPU、更多内存)。简单,但有物理上限,且成本增长快;
  • 横向扩展(Scale Out):加更多机器。理论上无上限,但需要把流量分配给它们——这就是负载均衡。

工作层次

四层负载均衡(L4)

工作在传输层(TCP/UDP)。基于 IP + 端口做转发。

它不解析 HTTP 内容,只看数据包的地址信息。处理速度快,开销小。

七层负载均衡(L7)

工作在应用层(HTTP)。可以解析 HTTP 请求,基于 URL、主机名、Cookie、Header 等做路由。

灵活性强(如把 /api 的请求转发到 API 服务器,把 /static 的请求转发到静态资源服务器),但处理开销大。

常见算法

轮询(Round Robin):依次分配给每台服务器。简单,但不考虑服务器的实际负载和性能差异。

加权轮询:给性能强的服务器分配更高的权重。

最少连接(Least Connections):把新请求发给当前连接数最少的服务器。适合长连接场景(如 WebSocket)。

源地址哈希:根据客户端 IP 计算哈希,保证同一客户端总是落到同一服务器。这提供了会话保持(Session Affinity)——但缺点是不利于扩展,且客户端分布不均时容易失衡。

一致性哈希:改进方案。把服务器和请求都映射到一个哈希环上,服务器增减时只影响相邻的一小部分请求,而不是全部重新分配。

健康检查

负载均衡器必须持续检查后端服务器的健康状态:

  • 主动检查:定期发送探测请求(如请求 /health);
  • 被动检查:根据真实请求的响应情况判断(如连续多次超时或返回 5xx 就标记为不健康)。

发现故障后,把该服务器从可用列表中摘除;恢复后重新加入。

会话状态问题

如果应用把用户会话存在服务器本地内存中,那么负载均衡导致用户请求落到不同服务器时,会话就丢失了。

三种解法:

一、会话保持:让同一用户总是访问同一台服务器。简单,但破坏了扩展性和容错性(该服务器宕机,其上的会话全丢)。

二、共享存储:把会话存到外部的共享存储(如 Redis、数据库)。服务器变成无状态的,可以任意扩缩容。这是推荐做法。

三、无状态设计:用 JWT 一类的令牌,把状态放在客户端。

负载均衡器本身的高可用

负载均衡器是单点故障——它挂了,整个服务就不可用了。

解法:

  • 多台负载均衡器做主备或集群;
  • 使用 VIP(虚拟 IP)配合 VRRP 等协议实现故障切换;
  • 或者使用 DNS 轮询 + 健康检查,在 DNS 层面做故障转移(切换较慢)。

一个进阶话题

在微服务架构中,负载均衡常常下沉到服务网格或客户端负载均衡:每个服务自己维护可用实例列表并选择目标,从而避免中心化的负载均衡器成为瓶颈。

说明:本文为分布式系统架构的公开知识整理。