【Nginx】负载均衡配置详解
Nginx作为高性能的HTTP服务器和反向代理服务器,提供了强大的负载均衡功能。本文将详细介绍Nginx负载均衡的配置方法和相关策略。
一、基础负载均衡配置
1.单服务示例配置
配置nginx.conf
模块
在Nginx配置文件中定义upstream模块:
worker_processes auto;events {worker_connections 1024;
}http{upstream backend {server 192.168.1.101:8080;server 192.168.1.102:8080;server 192.168.1.103:8080;}server {listen 80;server_name example.com;location / {proxy_pass http://backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}}
}
2.多服务配置
worker_processes auto;events {worker_connections 1024;
}http{# 定义一个新的日志格式,包含 upstream_addrlog_format custom '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" ''upstream: $upstream_addr';upstream server1{server 192.168.211.5:9529;server 192.168.211.169:9529;}upstream server2{server 192.168.211.5:9528;server 192.168.211.169:9528;}server {listen 80;server_name localhost;# 使用自定义的日志格式access_log /opt/nginx/logs/access.log custom;location ~ ^/server1/(.*)$ {proxy_pass http://server1/$1;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_set_header Content-Type application/json;}location ~ ^/server2/(.*)$ {proxy_pass http://server2/$1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}location ~* \.(css|js|html)$ {root /opt/nginx/html; # 在本例中的绝对路径为 /usr/local/nginx/html}error_page 404 /404.html;error_page 500 502 503 504 /50x.html;}
}
3.docker启动nginx脚本
该脚本需要根据自己的docker镜像启动nginx的配置去修改
#!/bin/bash# 定义变量
CONTAINER_NAME="nlb-nginx"
IMAGE_NAME="nginx:1.26"
HOST_PORT="9090" # 主机端口
CONTAINER_PORT="80" # 容器端口
PORT_MAPPING="${HOST_PORT}:${CONTAINER_PORT}"
NGINX_CONF_PATH="$(pwd)/nginx_server/nginx.conf"
LOG_DIR="/var/server1/logs/proxy"
TEST_URL="http://localhost:${HOST_PORT}"# 确保日志目录存在
if [ ! -d "$LOG_DIR" ]; thenecho "Creating log directory: $LOG_DIR"mkdir -p "$LOG_DIR" || {echo "Failed to create log directory."exit 1}
fi# 停止并删除旧容器(如果存在)
echo "Stopping and removing existing container: $CONTAINER_NAME"
docker stop "$CONTAINER_NAME" > /dev/null 2>&1
docker rm -f "$CONTAINER_NAME" > /dev/null 2>&1# 启动新的 Nginx 容器
echo "Starting new Nginx container: $CONTAINER_NAME"
docker run -itd \--name "$CONTAINER_NAME" \-p "$PORT_MAPPING" \-v "$NGINX_CONF_PATH:/opt/nginx/etc/nginx.conf" \-v "$LOG_DIR:/opt/nginx/logs" \"$IMAGE_NAME" \/opt/nginx/sbin/nginx -c /opt/nginx/etc/nginx.conf -g "daemon off;" || {echo "Failed to start container $CONTAINER_NAME."exit 1
}# 验证容器状态
echo "Verifying container status..."
if docker ps -f name="$CONTAINER_NAME" | grep -q "$CONTAINER_NAME"; thenecho "Container $CONTAINER_NAME is running successfully."
elseecho "Container $CONTAINER_NAME failed to start."exit 1
fi# 测试访问
echo "Testing access to $TEST_URL..."
if curl -s -o /dev/null -w "%{http_code}" "$TEST_URL" | grep -q "200"; thenecho "Nginx is accessible at $TEST_URL"
elseecho "Failed to access Nginx at $TEST_URL"exit 1
fiecho "Deployment completed successfully!"
4.测试负载均衡-脚本
1.后端服务
示例:使用 Python Flask 实现
在每台后端服务器上运行以下简单的 Flask 应用程序:
后端服务器 1 (192.168.211.5):
from flask import Flaskapp = Flask(__name__)@app.route('/nginx_test')
def server_info():return "192.168.211.5"if __name__ == '__main__':app.run(host='0.0.0.0', port=9529)
后端服务器 2 (192.168.211.75):
from flask import Flaskapp = Flask(__name__)@app.route('/nginx_test')
def server_info():return "192.168.211.75"if __name__ == '__main__':app.run(host='0.0.0.0', port=9529)
2.前端html测试
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Test Nginx Smartlabel</title>
</head>
<body><h1>Nginx and Flask Test Page</h1><p>Server Response: <strong id="server-response">Loading...</strong></p><script>// JavaScript to send a GET request to the Flask endpointfetch('/server1/nginx_test', {method: 'GET'}).then(response => response.json()) // Parse the JSON response.then(data => {document.getElementById('server-response').innerText = JSON.stringify(data);}).catch(error => {document.getElementById('server-response').innerText = 'Error fetching data';});</script>
</body>
</html>
- 访问测试页面
打开浏览器并访问 http://localhost:9090/test.html。页面会显示类似以下内容:
Nginx and Flask Test Page
Server Response: {"ip_info":"192.168.211.236","server":"server1"}
二、负载均衡策略
Nginx支持多种负载均衡算法:
- 轮询(默认)
upstream backend {server 192.168.1.101;server 192.168.1.102;
}
- 加权轮询
upstream backend {server 192.168.1.101 weight=3;server 192.168.1.102 weight=1;
}
- IP哈希(保持会话)
upstream backend {ip_hash;server 192.168.1.101;server 192.168.1.102;
}
- 最少连接数
upstream backend {least_conn;server 192.168.1.101;server 192.168.1.102;
}
- 基于响应时间(商业版)
upstream backend {fair;server 192.168.1.101;server 192.168.1.102;
}
三、高级配置选项
- 服务器状态参数
upstream backend {server 192.168.1.101 max_fails=3 fail_timeout=30s;server 192.168.1.102 backup;server 192.168.1.103 down;
}
- max_fails: 最大失败次数
- fail_timeout: 失败超时时间
- backup: 备用服务器
- down: 标记服务器不可用
- 健康检查(商业版)
upstream backend {zone backend 64k;server 192.168.1.101;server 192.168.1.102;health_check interval=5s fails=3 passes=2 uri=/health;
}
四、TCP/UDP负载均衡
Nginx也可以用于TCP/UDP负载均衡:
stream {upstream tcp_backend {server 192.168.1.101:3306;server 192.168.1.102:3306;}server {listen 3306;proxy_pass tcp_backend;}
}
五、最佳实践
- 会话保持:对于需要会话的应用,使用ip_hash或sticky模块
- 健康检查:配置合理的健康检查参数
- 日志记录:记录后端服务器的响应时间和状态
- 超时设置:适当调整proxy连接超时时间
- 缓冲区优化:根据应用特点调整缓冲区大小
六、常见问题
- 502错误:检查后端服务器是否可用
- 负载不均:调整权重或更换算法
- 性能问题:优化worker_processes和worker_connections
七、总结
通过合理配置Nginx负载均衡,可以显著提高系统的可用性和性能。根据实际业务需求选择合适的负载均衡策略和参数配置是关键。