Nginx不只是一个反向代理,它的负载均衡能力同样强大。当后端有多台服务器时,Nginx负责把请求合理分配过去。
今天把四种负载均衡策略从原理到配置讲清楚。
基本配置
nginx
# 定义上游服务器组
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
默认就是轮询策略。
策略一:轮询(Round Robin)
按顺序依次分配请求,最公平。
nginx
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
erlang
请求1 → 10号机
请求2 → 11号机
请求3 → 12号机
请求4 → 10号机
...
适合后端服务器性能一致的场景。
策略二:加权轮询(Weighted)
按权重分配,性能好的机器多接一些。
nginx
upstream backend {
server 192.168.1.10:8080 weight=3; # 3/6的请求
server 192.168.1.11:8080 weight=2; # 2/6的请求
server 192.168.1.12:8080 weight=1; # 1/6的请求
}
适合服务器配置不一样的场景------比如新旧机器混用。
策略三:IP哈希(ip_hash)
根据客户端IP的hash值,固定分配到同一台后端。
nginx
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
好处:同一个用户始终访问同一台机器,session不会丢。
缺点:如果用户量大,可能分配不均匀。而且某台机器挂了,session还是会丢。
| 对比 | 优点 | 缺点 |
|---|---|---|
| 简单 | 配置一行就够 | 分配可能不均匀 |
| session保持 | 不需要额外组件 | 机器挂了session丢 |
现在更推荐用Redis集中存session,而不是依赖ip_hash。
策略四:最少连接(least_conn)
把请求分配给当前连接数最少的服务器。
nginx
upstream backend {
least_conn;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
适合请求处理时间差异大的场景------长连接、大文件下载等。
健康检查和故障转移
nginx
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup; # 备用机,其他都挂了才用
}
| 参数 | 含义 |
|---|---|
| max_fails | 连续失败几次后标记为不可用 |
| fail_timeout | 标记不可用后30秒不分配请求 |
| backup | 备用服务器 |
| down | 永久不参与负载均衡 |
完整的Nginx负载均衡配置
nginx
upstream backend {
least_conn;
server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.13:8080 backup;
keepalive 32; # 保持32个长连接
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超时配置
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
# 重试配置
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;
}
}
四种策略对比
| 策略 | 配置 | 适用场景 | 注意事项 |
|---|---|---|---|
| 轮询 | 默认 | 服务器性能一致 | 最常用 |
| 加权轮询 | weight | 服务器性能不一致 | --- |
| ip_hash | ip_hash | 需要session保持 | 推荐用Redis替代 |
| least_conn | least_conn | 请求处理时间差异大 | 长连接场景 |
Nginx负载均衡配置简单但功能强大。大部分场景用轮询或加权轮询就够了,特殊场景再考虑其他策略。
你们项目里Nginx用的什么负载均衡策略?