Nginx作为高性能的HTTP服务器和反向代理服务器,提供了强大的负载均衡功能。本文将详细介绍Nginx负载均衡的配置方法和相关策略。
一、基础负载均衡配置
1.单服务示例配置
配置nginx.conf
模块
在Nginx配置文件中定义upstream模块:
powershell
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.多服务配置
powershell
worker_processes auto;
events {
worker_connections 1024;
}
http{
# 定义一个新的日志格式,包含 upstream_addr
log_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的配置去修改
powershell
#!/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" ]; then
echo "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"; then
echo "Container $CONTAINER_NAME is running successfully."
else
echo "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"; then
echo "Nginx is accessible at $TEST_URL"
else
echo "Failed to access Nginx at $TEST_URL"
exit 1
fi
echo "Deployment completed successfully!"
4.测试负载均衡-脚本
1.后端服务
示例:使用 Python Flask 实现
在每台后端服务器上运行以下简单的 Flask 应用程序:
后端服务器 1 (192.168.211.5):
python
from flask import Flask
app = 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):
python
from flask import Flask
app = 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测试
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 endpoint
fetch('/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。页面会显示类似以下内容:
bash
Nginx and Flask Test Page
Server Response: {"ip_info":"192.168.211.236","server":"server1"}
二、负载均衡策略
Nginx支持多种负载均衡算法:
- 轮询(默认)
powershell
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
}
- 加权轮询
powershell
upstream backend {
server 192.168.1.101 weight=3;
server 192.168.1.102 weight=1;
}
- IP哈希(保持会话)
powershell
upstream backend {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
}
- 最少连接数
powershell
upstream backend {
least_conn;
server 192.168.1.101;
server 192.168.1.102;
}
- 基于响应时间(商业版)
powershell
upstream backend {
fair;
server 192.168.1.101;
server 192.168.1.102;
}
三、高级配置选项
- 服务器状态参数
powershell
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: 标记服务器不可用
- 健康检查(商业版)
powershell
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负载均衡:
powershell
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负载均衡,可以显著提高系统的可用性和性能。根据实际业务需求选择合适的负载均衡策略和参数配置是关键。