nginx负载均衡实践操作
配置Nginx实现负载均衡
一、准备环境
至少三台如下机器:
| 服务器角色 | IP 地址 | 核心服务 |
|---|---|---|
| 负载均衡服务器 | 10.1.1.23 | Nginx |
| Web 服务器 1 | 10.1.1.34 | Nginx |
| Web 服务器 2 | 10.1.1.36 | Nginx |
其中 10.1.1.34 和 10.1.1.36 需部署好静态站点,且单独访问能正常打开站点,配置示例如下:
# 10.1.1.34## 写入一个简单的 HTMLecho "<h1>Hello Nginx! 这是我的第一个示例页面。</h1>" > /usr/local/nginx/html/index.html## 创建站点配置文件cat > /usr/local/nginx/conf/conf.d/site.conf <<'EOF'server { listen 80; server_name localhost;
root /usr/local/nginx/html; index index.html; charset utf-8;
location / { try_files $uri $uri/ =404; }
error_page 404 /404.html;}EOF## 重载 Nginxnginx -tnginx -s reload
# 10.1.1.36## 写入一个简单的 HTMLecho "<h1>Hello Nginx! 这是我的第二个示例页面。</h1>" > /usr/local/nginx/html/index.html## 创建站点配置文件cat > /usr/local/nginx/conf/conf.d/site.conf <<'EOF'server { listen 80; server_name localhost;
root /usr/local/nginx/html; index index.html; charset utf-8;
location / { try_files $uri $uri/ =404; }
error_page 404 /404.html;}EOF## 重载 Nginxnginx -tnginx -s reload二、配置Nginx负载均衡
2.1 创建Nginx配置文件
在 10.1.1.23 负载均衡服务器中,在 Nginx 安装目录的 conf/conf.d 目录下,创建名为 load_balance.conf 的配置文件,并添加以下内容:
cat > /usr/local/nginx/conf/conf.d/load_balance.conf <<'EOF'upstream web_servers { server 10.1.1.34:80 weight=1 max_fails=3 fail_timeout=30s; server 10.1.1.36:80 weight=1 max_fails=3 fail_timeout=30s; keepalive 32;}
server { listen 80; server_name _;
location / { proxy_pass http://web_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 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
proxy_http_version 1.1; proxy_set_header Connection ""; }}EOF参数解释:
upstream模块:定义“后端资源池”,这一块定义了具体有哪些服务器在干活。
upstream web_servers:给这组服务器起个名字叫web_servers。server 10.1.1.34:80 ...:
weight=1:加权轮询,表示权重,默认为1,数值越大分配请求越多。这里设置两台都为1,表示请求会按1:1的比例轮询分发。max_fails=3:如果在30秒内连接失败了3次,Nginx 会认为这台机器宕机了不可用。fail_timeout=30s:配合上面的参数,表示判定失效的时间周期。keepalive 32:性能优化关键点。Nginx 会与后端服务器保持 32 个长连接,避免每次请求都重新进行 TCP 三次握手,大大降低延迟并节省 CPU。
server模块:监听与入口。
listen 80;:Nginx 代理服务器本身监听 80 端口。server_name _;:这是一个泛域名写法,表示匹配所有指向这台服务器 IP 的请求。
location /:代理与转发逻辑,这里决定了请求如何被“加工”并送到后端。
转发核心:
proxy_pass http://web_servers;:核心指令。告诉 Nginx 把请求扔给刚才在upstream里定义的那个池子。超时设置(稳定性保障):
proxy_set_header Host $host;:把客户端请求的原始域名传给后端。
proxy_set_header X-Real-IP $remote_addr;:把 客户端真实的 IP 传给后端。
proxy_set_header X-Forwarded-For ...:记录完整的代理链路 IP。如果中间经过了多层代理,这个头会像接力棒一样记录所有 IP。长连接优化:
proxy_connect_timeout 60s;:Nginx 连接后端服务器的最长等待时间。
proxy_read_timeout 60s;:后端服务器处理完逻辑,把结果传回给 Nginx 的最长等待时间(如果后端业务很慢,这个值要调大)。
proxy_http_version 1.1;和proxy_set_header Connection "";:这两行必须配合upstream里的keepalive使用。它们强制 Nginx 使用 HTTP/1.1 协议与后端通信,并清除默认的Close头部,从而真正开启长连接模式。
2.2 重载Nginx
nginx -tnginx -s reload2.3 验证配置
2.3.1 快速验证
这种方法通过让两台 Web 服务器返回不同的标识内容,直观看到请求被分发到不同服务器。
步骤 1:在两台 Web 服务器添加标识文件
分别登录 10.1.1.34 和 10.1.1.36 服务器,在静态站点根目录创建测试文件:
# 10.1.1.34echo "This is Web Server 10.1.1.34" > /usr/local/nginx/html/test.txt
# 10.1.1.36echo "This is Web Server 10.1.1.36" > /usr/local/nginx/html/test.txt步骤 2:客户端多次访问负载均衡服务器
在任意能访问 10.1.1.23 服务器的机器上(本地电脑 / 服务器)执行多次 curl 命令:
for i in {1..10}; do curl http://10.1.1.23/test.txt; echo; done执行结果中,输出会交替出现 This is Web Server 10.1.1.34 和 This is Web Server 10.1.1.36,说明请求被均衡分发(权重均为 1 时,数量大致各占一半):
This is Web Server 10.1.1.34
This is Web Server 10.1.1.36
This is Web Server 10.1.1.34
This is Web Server 10.1.1.362.3.2 日志验证
通过查看两台 Web 服务器的 Nginx 访问日志,统计请求数量,验证分发均衡性。
步骤 1:查看 Nginx 访问日志
# 10.1.1.34## 实时查看新增请求tail -f /usr/local/nginx/logs/access.log## 或统计总请求数grep "GET /" /usr/local/nginx/logs/access.log | wc -l
# 10.1.1.36## 实时查看新增请求tail -f /opt/nginx/logs/access.log## 或统计总请求数grep "GET /" /opt/nginx/logs/access.log | wc -l关键日志信息解读:
日志中会显示 **负载均衡服务器 10.1.1.23 **作为请求来源,例如:
10.22.51.47 - - [07/Mar/2026:13:37:36 +0800] "GET /test.txt HTTP/1.1" 200 31 "-" "curl/7.29.0" "10.22.51.47" "10.1.1.23"多次访问后,10.1.1.34 和 10.1.1.36 服务器的日志中都会出现此类记录,且数量基本相等。
注:这里的日志格式配置为:
Terminal window log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for" "$realip_remote_addr"';一般情况下,对于后端服务器来说,直接和它“握手”建立连接的是负载均衡器,因此:
$remote_addr:默认获取的是直接连接者的 IP,即10.1.1.23。$http_x_forwarded_for:这是负载均衡器在转发时塞进 HTTP 头部的信息,里面才包含原始客户端的 IP10.22.51.47。而这里因为配置了:
Terminal window set_real_ip_from 10.1.1.23; # 设置负载均衡器的 IP 段(信任这个 IP 发来的头部信息)real_ip_header X-Forwarded-For; # 指定从 X-Forwarded-For 头部获取真实的客户端 IPreal_ip_recursive on; # 递归排除掉信任的代理 IP从而使Nginx 的变量行为会发生反转:
变量名 配置前 配置后(开启 RealIP) $remote_addr10.1.1.23 (LB IP) 10.22.51.47 (客户端 IP) $realip_remote_addr10.1.1.23 (LB IP) 10.1.1.23 (LB IP)
2.3.3 进阶验证
若想更直观看到负载均衡的状态(如后端服务器健康状态、请求数),可开启 Nginx 的 stub_status 状态模块。
步骤 1:在Web服务器修改 Nginx 配置
在 server 块中添加状态监控配置:
cat > /usr/local/nginx/conf/conf.d/site.conf <<'EOF'server { listen 80; server_name localhost;
root /usr/local/nginx/html; index index.html; charset utf-8;
location / { try_files $uri $uri/ =404; }
location /nginx_status { stub_status on; allow 127.0.0.1; # 允许本机访问 allow 10.22.51.0/24; # 允许内网段访问 deny all; # 拒绝其他所有访问 }
error_page 404 /404.html;}EOF步骤 2:重载 Nginx
nginx -tnginx -s reload步骤 3:在负载均衡服务器访问状态页
curl http://127.0.0.1/nginx_status状态页输出解读(关键信息):
Active connections: 2server accepts handled requests 10 10 20Reading: 0 Writing: 1 Waiting: 1
# 结合 upstream 状态(需额外模块,可选)# 主流方式:通过上述日志/测试文件验证即可三、七层代理与四层代理
3.1 七层代理(HTTP/HTTPS 层)
完整七层代理配置:
user root;worker_processes auto;
error_log logs/error.log;pid logs/nginx.pid;
events { worker_connections 1024;}
http { include mime.types; include conf.d/*.conf; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on; tcp_nopush on; keepalive_timeout 65; gzip on;
# 后端 Web 集群(核心配置,保留) upstream web_servers { server 10.1.1.34:80 weight=1 max_fails=3 fail_timeout=30s; server 10.1.1.36:80 weight=1 max_fails=3 fail_timeout=30s; keepalive 32; # 复用与后端的长连接(需配合 proxy_http_version 1.1) }
# HTTP 七层代理(80端口) server { listen 80; server_name _; # 匹配所有IP/域名访问
location / { proxy_pass http://web_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 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 启用 HTTP/1.1 支持长连接 proxy_http_version 1.1; proxy_set_header Connection ""; } }
# 可选:HTTPS 七层代理(若需配置证书) server { listen 443 ssl http2; server_name _; # 替换为你的域名,如 www.example.com
# SSL 证书配置(证书放在负载均衡服务器 10.1.1.23 上) ssl_certificate /usr/local/nginx/ssl/server.crt; # 你的证书路径 ssl_certificate_key /usr/local/nginx/ssl/server.key; # 你的私钥路径 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
location / { proxy_pass http://web_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_set_header X-Forwarded-Proto $scheme; # 传递 HTTPS 标识 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_http_version 1.1; proxy_set_header Connection ""; } }}3.2 四层代理(TCP 层)
四层代理不解析 HTTP 内容,仅转发 TCP 流量,需在 stream 块中配置(与 http 块同级)。
完整四层配置:
user root;worker_processes auto;
error_log logs/error.log;pid logs/nginx.pid;
events { worker_connections 1024;}
# 四层 TCP 代理核心配置(与 http 块同级,不能嵌套!)stream { # 定义后端 TCP 集群(针对 80 端口) upstream web_tcp_80 { server 10.1.1.34:80 weight=1 max_fails=3 fail_timeout=30s; server 10.1.1.36:80 weight=1 max_fails=3 fail_timeout=30s; # 四层健康检查(Nginx 1.19+ 支持,低版本可省略) health_check interval=3s timeout=1s passes=2 fails=2; }
# 监听 80 端口,转发 TCP 流量(四层核心) server { listen 80; # 四层监听 TCP 80 端口(无 http/ssl 标识) proxy_pass web_tcp_80; # 四层超时配置 proxy_connect_timeout 5s; # 连接后端超时 proxy_timeout 300s; # 连接保持超时 # 可选:传递客户端真实 IP(需后端支持 Proxy Protocol) # proxy_protocol on; }
# 可选:四层代理 HTTPS(443 端口,后端直接处理 SSL 证书) upstream web_tcp_443 { server 10.1.1.34:443 weight=1 max_fails=3 fail_timeout=30s; server 10.1.1.36:443 weight=1 max_fails=3 fail_timeout=30s; } server { listen 443; proxy_pass web_tcp_443; proxy_connect_timeout 5s; proxy_timeout 300s; }}
# 原有 http 块可保留(若不需要七层代理,可注释/删除)http { include mime.types; include conf.d/*.conf; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on; tcp_nopush on; keepalive_timeout 65; gzip on;}3.3 两种代理的核心差异
| 维度 | 七层代理 | 四层代理 |
|---|---|---|
| 工作层级 | HTTP/HTTPS(应用层) | TCP/UDP(传输层) |
| 配置块 | http 块(upstream+server) | stream 块(与 http 同级) |
| 核心能力 | 1. 解析 URL / 请求头 / 域名 2. 传递 X-Real-IP 等 HTTP 头3. 支持 SSL 终结(负载均衡端处理证书) 4. 可按 URL 路由(如 /static 定向到 34) | 1. 仅转发端口流量,无内容解析 2. 无法修改 HTTP 头,传递 IP 需 Proxy Protocol3. SSL 透传(后端 34/36 处理证书) 4. 无 URL 路由能力 |
| 你的场景适配性 | ✅ 最优(静态站点负载均衡,可优化缓存 / IP 传递) | ❗ 仅适合需透传 HTTPS / 不解析 HTTP 的场景 |
| 配置验证命令 | nginx -t(同常规) | nginx -t(需确保 stream 模块存在) |
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
赣公网安备36072602000131号