Nginx 负载均衡配置指南 🔄
🚀 全面掌握 Nginx 负载均衡配置,构建高可用、高性能的 Web 服务架构
✨ 特点和功能
Nginx 负载均衡提供以下强大功能:
- ⚡ 高性能处理:基于事件驱动的异步架构,轻松处理数万并发连接
- 🔄 多种算法:支持轮询、加权轮询、IP哈希、最少连接等多种负载均衡算法
- 🛡️ 高可用性:支持健康检查和自动故障转移,确保服务持续可用
- 📊 灵活配置:支持四层和七层负载均衡,满足不同场景需求
- 🔍 实时监控:提供状态监控和日志记录,便于故障排查和性能优化
- 🌐 多协议支持:支持 HTTP、HTTPS、TCP、UDP 等多种协议
- 💡 易于扩展:简单配置即可添加或移除后端服务器,支持动态扩展
📖 目录导航
🔥 一、热备负载均衡(生产环境推荐)
热备模式:当主服务器发生故障时,自动启用备份服务器提供服务。请求处理顺序:AAAAAA 突然 A 挂了,BBBBBBBBBBBB…
1. 创建 mtab 配置文件
mtab 书签页:
https://mtab.mobufan.eu.org:5553
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
## nginx 反向代理+负载均衡: mtab 书签页
upstream mysvr {
server 10.10.10.245:9200;
## 负载均衡-热备模式:有2台服务器,一台服务器宕机时,才启用第二台服务器提供服务
server 10.10.10.247:9200 backup; ## 热备
}
server {
## 监听5553端口,并启用SSL
listen 5553 ssl;
listen [::]:5553 ssl;
## 替换为你的域名
server_name mtab.mobufan.eu.org;
## 指定 SSL 证书文件和私钥文件的路径
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
## 指定反向代理的服务地址
proxy_pass http://mysvr; ## 负载均衡 变量地址(不能和其它服务器相同)
add_header backendIP $upstream_addr; ## 负载均衡 节点IP
add_header backendCode $upstream_status; ## 负载均衡 响应状态码
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
proxy_redirect off;
proxy_buffering on; #开启缓存
# 使用 HTTP/1.1 协议与后端服务器通信
proxy_http_version 1.1;
client_max_body_size 20000m;
}
}
|
2. 应用配置
1
2
3
4
5
6
7
8
|
# 测试配置文件
sudo nginx -t
# 重新加载配置
sudo nginx -s reload
# 查看 Nginx 状态
sudo systemctl status nginx
|
3. 验证负载均衡
访问:https://mtab.mobufan.eu.org:5553
打开浏览器开发者工具,选择网络选项卡,找到 mtab.mobufan.eu.org 请求,查看响应头中的 backendIP
和 backendCode
字段。
🔄 二、轮询负载均衡
轮询:Nginx 默认策略,权重默认为 1,服务器处理请求的顺序:ABABABABAB…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
upstream backend_servers {
# 默认权重为1
server 127.0.0.1:7878;
server 192.168.10.121:3333;
}
server {
listen 8081; # 监听端口
server_name 127.0.0.1; # 监听地址
location / {
proxy_pass http://backend_servers; # 请求转向 backend_servers 定义的服务器列表
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
|
⚖️ 三、加权轮询负载均衡
加权轮询:根据配置的权重大小分发不同数量的请求。下面服务器的请求顺序为:ABBABBABBABBABB…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
upstream backend_servers {
server 127.0.0.1:7878 weight=1;
server 192.168.10.121:3333 weight=2;
server 192.168.10.122:4444 weight=3;
}
server {
listen 8081; # 监听端口
server_name 127.0.0.1; # 监听地址
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 添加响应头显示后端服务器信息
add_header X-Backend $upstream_addr;
}
}
|
🔐 四、IP Hash 负载均衡
ip_hash: Nginx 会让相同的客户端 IP 请求相同的服务器,适用于需要会话保持的场景。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
upstream backend_servers {
ip_hash; # 基于客户端IP的哈希算法
server 127.0.0.1:7878;
server 192.168.10.121:3333;
server 192.168.10.122:4444;
}
server {
listen 8081;
server_name 127.0.0.1;
# 启用访问日志记录负载均衡信息
access_log /var/log/nginx/loadbalancer.access.log upstreamlog;
location / {
proxy_pass http://backend_servers;
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 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
}
|
📁 五、基于特定资源的负载均衡
通过多个 upstream 分成多个服务器组,将不同的请求分流到不同的服务器组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
# 定义日志格式
log_format upstreamlog '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream: $upstream_addr '
'upstream_status: $upstream_status '
'request_time: $request_time';
# 视频服务器组
upstream video_servers {
server 127.0.0.1:7878 weight=1;
server 192.168.10.121:3333 weight=2;
}
# 文件服务器组
upstream file_servers {
server 192.3.2.1:7878 weight=1;
server 192.3.2.2:3333 weight=2;
}
server {
listen 8081;
server_name 127.0.0.1;
access_log /var/log/nginx/access.log upstreamlog;
# 视频请求路由
location /video/ {
proxy_pass http://video_servers;
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_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
# 文件请求路由
location /file/ {
proxy_pass http://file_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 大文件传输优化
client_max_body_size 100M;
proxy_request_buffering off;
}
}
|
🌐 六、基于不同域名的负载均衡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# 视频服务器组
upstream video_servers {
server 127.0.0.1:7878 weight=1;
server 192.168.10.121:3333 weight=2;
}
# 文件服务器组
upstream file_servers {
server 192.3.2.1:7878 weight=1;
server 192.3.2.2:3333 weight=2;
}
# 视频域名服务器
server {
listen 80;
server_name video.example.com;
location / {
proxy_pass http://video_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 添加CORS头部
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
}
# 文件域名服务器
server {
listen 80;
server_name file.example.com;
location / {
proxy_pass http://file_servers;
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_max_temp_file_size 0;
proxy_buffering off;
}
}
|
🔄 七、带有 URL 重写的负载均衡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
upstream backend_servers{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 80;
server_name localhost;
# URL重写规则
location /file/ {
rewrite ^(/file/.*) /server/$1 last;
}
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 健康检查
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
}
|
🌐 八、四层负载均衡
注意:四层负载均衡需要在 stream 模块中配置,通常用于 TCP/UDP 负载均衡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# 在nginx.conf的main上下文中添加
stream {
# 定义日志格式
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr"';
access_log /var/log/nginx/stream.access.log basic;
# Redis服务器组
upstream redis_backend {
server 192.168.200.146:6379 weight=1;
server 192.168.200.146:6378 weight=2;
}
# Tomcat服务器组
upstream tomcat_backend {
server 192.168.200.146:8080;
server 192.168.200.147:8080 backup;
}
# MySQL服务器组
upstream mysql_backend {
server 192.168.200.148:3306;
server 192.168.200.149:3306 backup;
}
# Redis负载均衡
server {
listen 6379;
proxy_pass redis_backend;
proxy_timeout 1s;
proxy_connect_timeout 1s;
}
# Tomcat负载均衡
server {
listen 8080;
proxy_pass tomcat_backend;
proxy_timeout 3s;
}
# MySQL负载均衡
server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 5s;
}
}
|
💡 九、负载均衡参数详解
1. 服务器状态参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
upstream backend_servers {
# 基本参数
server backend1.example.com:8080 weight=5; # 权重
server backend2.example.com:8080 max_fails=3; # 最大失败次数
server backend3.example.com:8080 fail_timeout=30s; # 失败超时
# 高级参数
server backup1.example.com:8080 backup; # 备份服务器
server down1.example.com:8080 down; # 标记为永久不可用
server slow1.example.com:8080 slow_start=30s; # 慢启动时间
# 保持活动连接
keepalive 32; # 连接池大小
keepalive_timeout 60s; # 连接超时时间
}
|
2. 健康检查配置
1
2
3
4
5
6
7
8
9
10
11
12
|
upstream backend_servers {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 健康检查参数
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
# 会话保持
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
|
3. 超时和缓冲设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
upstream backend_servers {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
server {
location / {
proxy_pass http://backend_servers;
# 超时设置
proxy_connect_timeout 5s; # 连接超时
proxy_send_timeout 10s; # 发送超时
proxy_read_timeout 30s; # 读取超时
# 缓冲设置
proxy_buffering on; # 启用缓冲
proxy_buffer_size 4k; # 缓冲区大小
proxy_buffers 8 4k; # 缓冲数量和大小
proxy_busy_buffers_size 8k; # 忙碌时缓冲区大小
# 其他优化
proxy_redirect off; # 禁用重定向
proxy_http_version 1.1; # 使用HTTP/1.1
proxy_set_header Connection ""; # 清空连接头
}
}
|
🛠️ 十、高级配置技巧
1. 动态负载均衡
1
2
3
4
5
6
7
8
9
10
|
# 使用DNS解析实现动态服务发现
resolver 8.8.8.8 1.1.1.1 valid=30s;
upstream dynamic_backend {
zone upstream_dynamic 64k;
server service.example.com:8080 resolve;
# 定期解析DNS
resolver_timeout 30s;
}
|
2. 故障转移配置
1
2
3
4
5
6
7
8
9
10
|
upstream backend_servers {
server primary.example.com:8080;
server secondary.example.com:8080 backup;
server tertiary.example.com:8080 backup;
# 故障转移策略
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
}
|
3. 性能优化配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
upstream backend_servers {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 连接池配置
keepalive 32;
keepalive_requests 100;
keepalive_timeout 60s;
# 最少连接算法
least_conn;
}
server {
location / {
proxy_pass http://backend_servers;
# 缓冲优化
proxy_buffers 16 32k;
proxy_buffer_size 64k;
# 缓存优化
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}
|
🔍 十一、监控和调试
1. 启用状态页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# Nginx状态页面
server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
# 上游状态页面(需要nginx-upstream-status模块)
server {
listen 8081;
server_name localhost;
location /upstream_status {
upstream_status;
access_log off;
allow 127.0.0.1;
deny all;
}
}
|
2. 日志配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 定义上游日志格式
log_format upstream_log '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream: $upstream_addr '
'upstream_status: $upstream_status '
'request_time: $request_time '
'upstream_response_time: $upstream_response_time '
'upstream_connect_time: $upstream_connect_time';
# 应用日志格式
server {
access_log /var/log/nginx/access.log upstream_log;
error_log /var/log/nginx/error.log warn;
}
|
3. 实时监控脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/bin/bash
# monitor_upstream.sh - 监控Nginx上游服务器状态
LOG_FILE="/var/log/nginx/upstream_monitor.log"
UPSTREAM_NAME="backend_servers"
echo "$(date): 开始监控上游服务器 $UPSTREAM_NAME" >> $LOG_FILE
# 检查Nginx状态
if ! systemctl is-active --quiet nginx; then
echo "$(date): Nginx服务未运行" >> $LOG_FILE
exit 1
fi
# 获取上游服务器状态
UPSTREAM_STATUS=$(curl -s http://localhost:8081/upstream_status | grep $UPSTREAM_NAME)
if [ -z "$UPSTREAM_STATUS" ]; then
echo "$(date): 无法获取上游服务器状态" >> $LOG_FILE
else
echo "$(date): 上游服务器状态 - $UPSTREAM_STATUS" >> $LOG_FILE
fi
# 检查是否有服务器宕机
if echo "$UPSTREAM_STATUS" | grep -q "down"; then
echo "$(date): 警告:有上游服务器宕机" >> $LOG_FILE
# 发送警报
echo "Nginx上游服务器宕机警报: $UPSTREAM_STATUS" | mail -s "Nginx警报" admin@example.com
fi
|
🚨 十二、常见问题排查
1. 基础检查命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 检查Nginx配置语法
nginx -t
# 检查Nginx进程状态
ps aux | grep nginx
# 检查监听端口
netstat -tulnp | grep nginx
ss -tulnp | grep nginx
# 检查错误日志
tail -f /var/log/nginx/error.log
# 检查访问日志
tail -f /var/log/nginx/access.log
|
2. 负载均衡状态检查
1
2
3
4
5
6
7
8
9
10
|
# 测试负载均衡分配
for i in {1..10}; do
curl -s http://example.com/ | grep "Server IP"
done
# 检查上游服务器健康状态
curl http://localhost:8081/upstream_status
# 检查Nginx状态页面
curl http://localhost:8080/nginx_status
|
3. 性能问题排查
1
2
3
4
5
6
7
8
9
10
11
|
# 检查连接数
netstat -an | grep :80 | wc -l
# 检查活动连接数
nginx -T 2>/dev/null | grep active_connections
# 检查请求率
goaccess /var/log/nginx/access.log -a
# 检查响应时间
cat /var/log/nginx/access.log | awk '{print $NF}' | sort -n | uniq -c
|
📊 十三、负载均衡策略选择指南
策略类型 |
适用场景 |
优点 |
缺点 |
轮询 |
服务器性能相近,无状态服务 |
简单易用,公平分配 |
无法考虑服务器负载差异 |
加权轮询 |
服务器性能差异明显 |
考虑服务器性能差异,合理分配负载 |
配置相对复杂,需要了解服务器性能 |
IP Hash |
需要会话保持的应用 |
确保同一客户端访问同一服务器,保持会话 |
服务器宕机会影响部分用户,扩展性受限 |
最少连接 |
请求处理时间差异大 |
动态分配,考虑当前负载,更合理 |
需要维护连接数状态,稍微增加开销 |
URL Hash |
缓存优化场景 |
提高缓存命中率,减少重复计算 |
配置复杂,需要额外模块支持 |
响应时间 |
对响应速度敏感的应用 |
优先选择响应快的服务器,提升用户体验 |
需要实时监控响应时间,增加开销 |
选择建议
- 一般Web应用:使用加权轮询或最少连接算法
- 会话敏感应用:使用IP Hash算法保持会话一致性
- API网关:使用轮询或响应时间算法,确保公平和快速响应
- 缓存服务器:使用URL Hash算法,提高缓存命中率
- 高可用集群:结合备份服务器和健康检查,确保服务连续性
配置示例:最少连接算法
1
2
3
4
5
6
7
8
9
10
|
upstream backend_servers {
least_conn; # 最少连接算法
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1;
# 健康检查
check interval=3000 rise=2 fall=5 timeout=1000;
}
|
🚀 通过合理配置 Nginx 负载均衡,您可以构建高可用、高性能的 Web 服务架构,确保服务的稳定性和可扩展性。根据您的具体需求选择合适的负载均衡策略,并定期监控和优化配置!
💡 提示:
- 定期检查服务器健康状况和负载均衡效果
- 根据业务变化调整负载均衡策略和参数
- 启用监控和日志记录,便于故障排查和性能优化
- 在生产环境部署前充分测试所有配置
📚 扩展资源: