负载均衡 Nginx/HAProxy:算法与会话保持
负载均衡 Nginx/HAProxy 完全指南:算法与会话保持
引言
在高并发 Web 架构中,单台服务器往往无法承载所有流量。负载均衡器作为流量入口,能将请求合理分发到多台后端服务器,从而提升系统整体处理能力和可用性。Nginx 和 HAProxy 是业界最流行的两款开源反向代理与负载均衡软件。本教程将从初学者视角出发,系统讲解它们在负载均衡中的核心机制:负载均衡算法与会话保持,并提供可直接复用的配置示例。
负载均衡算法核心概念
算法决定了负载均衡器如何选择后端服务器。理解算法是正确调优性能、保证服务稳定性的前提。
静态算法(不考虑实时负载)
- 轮询(Round Robin)
按顺序将请求逐一分配给每台服务器,循环往复。实现简单,适合服务器性能一致且无状态服务的场景。 - 加权轮询(Weighted Round Robin)
为每台服务器预先设置权重,权重越高,分配的请求越多。适合后端服务器性能不均的情况。 - IP 哈希(IP Hash)
根据客户端 IP 地址计算哈希值,并将同一 IP 的请求固定到特定服务器。可实现简单的会话保持,但动态增减服务器时会话可能丢失。
动态算法(依赖实时状态)
- 最少连接(Least Connections)
将新请求分配给当前活动连接数最少的服务器。对长连接或处理时间差异大的服务更友好。 - 最短响应时间(Least Time)
结合连接数和历史响应时间分配请求,优先选择响应最快的服务器。仅部分负载均衡器支持。 - URL 哈希 / 一致性哈希
对请求 URL 或自定义 key 做哈希,同一资源的请求始终落到同一服务器,常用于缓存优化与持久化。
Nginx 负载均衡配置指南
基础 upstream 块
Nginx 通过 upstream 模块定义后端服务器组。以下为最简配置:
upstream backend {
server 10.0.0.1:80;
server 10.0.0.2:80;
}
常用算法及配置方法
1. 加权轮询(默认)
upstream backend {
server 10.0.0.1:80 weight=3;
server 10.0.0.2:80 weight=1;
}
权重比例 3:1,适合性能差异明显的服务器。
2. IP 哈希
upstream backend {
ip_hash;
server 10.0.0.1:80;
server 10.0.0.2:80;
}
注意:ip_hash 与 weight 可共存,但 Nginx 会基于“加权轮询 + 哈希”思想运作。服务器增减会重新映射部分客户端。
3. 最少连接
upstream backend {
least_conn;
server 10.0.0.1:80;
server 10.0.0.2:80;
}
least_conn 还支持结合权重使用:least_conn; 后再给每个 server 加 weight。
4. 一致性哈希(第三方模块或 Plus 版本)
Nginx Plus 提供 hash 指令,开源版可使用 ngx_http_upstream_hash_module 扩展。
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
}
Nginx 会话保持方案
Nginx 开源版不直接支持基于 Cookie 的会话保持。主流的解决方案有三种:
方案一:IP 哈希
如前所述,利用 ip_hash 实现简单的会话保持。缺点:客户端 IP 变化或服务器增减会导致会话重新分配;代理服务器后的所有用户会被视为同一 IP。
方案二:Sticky 模块(需编译或使用 Plus)
Nginx Plus 或第三方 nginx-sticky-module 提供基于 Cookie 的会话黏滞。
upstream backend {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server 10.0.0.1:80;
server 10.0.0.2:80;
}
客户端首次访问被分配服务器后,会收到名为 srv_id 的 Cookie,后续请求携带该 Cookie 即可路由到相同后端。
方案三:结合 Consul/DNS 动态发现 + 一致性哈希
利用服务发现工具动态更新 upstream,并通过 hash 指令保持会话。适合微服务架构。
HAProxy 负载均衡配置指南
基本配置结构
HAProxy 配置通常由 global、defaults、frontend 和 backend 段组成。负载均衡算法定义在 backend 中。
backend web_servers
balance roundrobin
server web1 10.0.0.1:80 check
server web2 10.0.0.2:80 check
支持的算法一览
- roundrobin:加权轮询,按服务器权重动态分配。
- static-rr:静态轮询,不依赖服务器运行时权重,性能更高但更改权重需重启。
- leastconn:最少连接数,长连接场景优选。
- source:源 IP 哈希,类似 Nginx 的
ip_hash,但支持一致性哈希选项。 - uri:对请求 URI(问号之前部分)做哈希,可保持缓存命中。
- url_param:对指定的 URL 参数值做哈希。
- hdr():使用指定的 HTTP 头部值做哈希。
- rdp-cookie:用于 RDP(远程桌面)的会话保持。
算法高级选项
balance source支持一致性哈希:
balance source
hash-type consistent
服务器上下线时仅重新映射少量用户,大幅减少会话丢失。
balance leastconn可配合weight按比例分配。
HAProxy 会话保持实现
HAProxy 提供极为灵活的会话保持机制,远超开源 Nginx 的选择。
1. 源 IP 地址保持(source)
backend app
balance source
hash-type consistent
server s1 10.0.0.1:80 check weight 1
server s2 10.0.0.2:80 check weight 1
优点:无需 Cookie,对客户端透明;缺点:同一 NAT 后的用户共享后端。
2. 基于 Cookie 的持久性 HAProxy 可以直接插入或学习 Cookie,方式多样:
cookie插入方式(Set-Cookie)
backend app
balance roundrobin
cookie SERVERID insert indirect nocache
server s1 10.0.0.1:80 cookie s1 check
server s2 10.0.0.2:80 cookie s2 check
说明:HAProxy 在响应中插入名为 SERVERID 的 Cookie,值为服务器标识 s1 或 s2。客户端后续请求携带该 Cookie,直接路由到指定服务器。
cookie学习方式(被动学习)
若应用自身已设置会话 Cookie,可用cookie SERVERID prefix或cookie SERVERID rewrite将 Cookie 前缀与服务器绑定,HAProxy 据此路由。
3. 基于 SSL Session ID 的保持
通过 stick-table 绑定 SSL Session ID 到特定服务器,实现加密层会话保持,解决 Cookie 禁用问题。
frontend https_front
bind *:443 ssl crt /etc/ssl/cert.pem
stick-table type binary len 32 size 30k expire 30m
stick on ssl_fc_session_id
default_backend web_servers
4. 通用 Stick-Table 机制
HAProxy 的 stick-table 可将任意属性(IP、Cookie、URL 参数等)与服务器持久绑定,是实现自定义会话保持的核心武器。
场景化选型与配置对比
| 需求场景 | Nginx 方案 | HAProxy 方案 |
|---|---|---|
| 简单轮询 | 默认 upstream 无特殊指令 |
balance roundrobin |
| 性能加权 | weight 指令 |
weight 指令 + balance roundrobin |
| 最少连接 | least_conn |
balance leastconn |
| IP 会话保持 | ip_hash |
balance source + hash-type consistent |
| 高级 Cookie 会话保持 | 第三方模块或 Nginx Plus 的 sticky |
原生 cookie insert/prefix/rewrite |
| SSL 会话保持 | 通常借助 ip_hash 或第三方模块 |
原生 stick-table 基于 SSL ID |
| 自定义 key 持久化 | hash 指令(Plus 或第三方模块) |
stick on + 任意 ACL 匹配 |
建议:
- 你的业务是无状态的 REST API,选最少连接算法,无需会话保持。
- 需要透明会话保持且客户端 IP 相对固定,使用源 IP 哈希(HAProxy 推荐一致性哈希以减小动态变更影响)。
- 必须支持 Cookie 会话保持(尤其场景跨越 NAT 或多台代理),HAProxy 是更优选择;Nginx 仅在 Plus 版本或引入第三方模块时才有相应能力。
- 两者均支持多后端组的组合管理,例如将静态资源转发至 Nginx,动态请求代理到应用服务器。
总结
掌握负载均衡算法与会话保持机制,是构建高可用、可扩展 Web 架构的关键技能。Nginx 以其高性能和静态资源处理见长,在简单会话保持场景下足够胜任;HAProxy 则提供了最全面的 Layer 4/7 负载均衡与原生持久化方案,尤其适合复杂的会话黏滞需求。理解两者配置背后的设计逻辑,能够帮助你在生产环境中快速做出合理的技术决策。
现在,你可以将文中配置模板直接应用于测试环境,逐步调试出最适合你业务形态的负载均衡策略。