Nginx 有哪些负载均衡策略?
简化版
Nginx 常用的负载均衡策略:① 轮询(round-robin,默认)——请求按顺序依次分给每台后端;② 加权轮询(weight)——给性能好的服务器配更高权重、分更多请求;③ ip_hash——按客户端 IP 哈希固定分给某台后端,解决会话保持(同一用户总落到同一台);④ least_conn——把请求分给当前连接数最少的服务器,适合请求处理时长差异大的场景;⑤ fair / url_hash(第三方模块)——按响应时间或 URL 分配。默认轮询,需要会话保持用 ip_hash。
详细版
配置示例:
upstream backend {
# 默认轮询
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 加权轮询:weight 越大分到越多请求
# server 192.168.1.10:8080 weight=3;
# server 192.168.1.11:8080 weight=1;
# ip_hash:同一 IP 固定到同一后端(会话保持)
# ip_hash;
# least_conn:分给连接数最少的
# least_conn;
}
server {
location / {
proxy_pass http://backend;
}
}
| 策略 | 分配依据 | 适用场景 |
|---|---|---|
| 轮询(默认) | 依次轮流 | 后端性能相近、无状态 |
| 加权轮询 | 按 weight 比例 | 后端性能不均 |
| ip_hash | 客户端 IP 哈希 | 需要会话保持(Session) |
| least_conn | 当前连接数最少 | 请求处理时长差异大 |
| fair(三方) | 响应时间最短优先 | 追求响应速度 |
| url_hash(三方) | 请求 URL 哈希 | 提升缓存命中(同 URL 到同后端) |
完整版教学
一、负载均衡要解决什么
当后端有多台服务器时,需要一个策略决定「每个请求该发给哪台」,目标是让流量合理分摊、不让某台过载、同时兼顾会话、缓存等需求。Nginx 通过 upstream 块定义后端服务器组,配合不同的负载均衡算法实现分发。不同策略适合不同场景,理解它们的分配依据和适用条件是重点。
二、轮询与加权轮询:最基础
轮询(round-robin) 是 Nginx 的默认策略:请求按顺序依次分给后端服务器(第 1 个请求给 A、第 2 个给 B、第 3 个给 C、第 4 个又给 A…)。简单、均匀,适合后端服务器性能相近、且服务无状态的场景。
加权轮询(weight):现实中服务器性能可能不同(有的 16 核、有的 4 核)。给每台配一个权重 weight,权重越高分到的请求越多。比如 A weight=3、B weight=1,则每 4 个请求,A 处理 3 个、B 处理 1 个。适合后端性能不均衡的情况,按能力分配。
三、ip_hash:解决会话保持
轮询有个问题:同一个用户的多次请求可能被分到不同后端。如果服务是有状态的(比如 Session 存在服务器本地内存里),用户第一次登录在 A 服务器建了 Session,第二次请求被轮询分到 B 服务器,B 上没有他的 Session,就会掉登录状态。
ip_hash 解决这个问题:按客户端 IP 计算哈希,同一个 IP 的请求总是被分到同一台后端服务器。这样同一用户的所有请求都落在同一台机器上,Session 就能保持。
- 优点:实现会话保持,简单。
- 缺点:如果某台后端挂了,落在它上面的用户会话会丢失并被重新分配;且如果大量用户来自同一个出口 IP(如公司 NAT),会导致负载不均。更好的会话方案是把 Session 外置到 Redis(让服务无状态),而非依赖 ip_hash。
四、least_conn:按当前负载分配
least_conn(最少连接):把新请求分给当前活跃连接数最少的后端服务器。
轮询/加权轮询假设「每个请求处理时长差不多」,但如果请求处理时长差异很大(有的请求几毫秒、有的要几秒),轮询可能把请求源源不断分给一台正在处理慢请求、已经很忙的服务器。least_conn 则动态看谁**当前连接最少(最闲)**就分给谁,能更好地应对处理时长不均的场景,让负载更均衡。
五、第三方策略:fair 与 url_hash
这两个需要安装第三方模块:
- fair:按后端的响应时间分配,响应快(负载轻)的优先分到请求。比 least_conn 更智能地衡量「谁更闲」,追求整体响应速度。
- url_hash:按请求的 URL 做哈希,相同 URL 的请求固定分到同一台后端。主要用于提升缓存命中率——比如后端做了本地缓存,同一个 URL 总落到同一台,那台的缓存命中率就高(常配合缓存服务器使用)。
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| 轮询 | 默认按顺序分发请求 |
| 权重 | 按机器能力分配不同流量 |
| ip_hash/least_conn | 会话保持或按连接数倾斜调度 |
upstream backend {
server app1 weight=3;
server app2 weight=1;
least_conn;
}
proxy_pass http://backend;
负载均衡策略要结合请求耗时、机器能力和会话状态,不能只背轮询。
- 误区:轮询一定公平。 请求耗时和机器配置不同,简单轮询可能让慢节点堆积。
- 误区:ip_hash 是万能会话方案。 ip_hash 会造成流量倾斜,客户端 NAT 后大量用户可能落到同一节点。
- 误区:加权只影响连接数不影响请求。 权重会影响请求分配比例,适合不同规格机器。
- 追问:least_conn 适合什么? 适合长连接或请求耗时差异大的场景,优先分给连接少的节点。
- 追问:后端故障如何摘除? 可配置失败次数、超时、健康检查,商业版/外部组件支持主动健康检查。
- 追问:灰度发布怎么做? 通过权重、独立 upstream、Header/Cookie 路由或网关层规则分流。
七、加强记忆
Nginx 负载均衡策略:① 轮询(默认)——依次轮流,适合后端性能相近、无状态;② 加权轮询(weight)——按权重比例分,适合性能不均;③ ip_hash——按客户端 IP 哈希固定到同一后端,解决会话保持(但挂机丢会话、NAT 下不均,更优是 Session 外置 Redis);④ least_conn——分给当前连接数最少的,适合请求处理时长差异大;**⑤ fair(响应时间)/ url_hash(同 URL 到同后端提升缓存命中)**是第三方模块。选择口诀:默认轮询、性能不均加权重、要会话保持用 ip_hash、时长差异大用 least_conn。