文章目录
一、前言
在搭建个人博客或部署微服务时,我们经常会遇到这样一个问题:服务器上跑了多个应用(比如 Spring Boot 项目、Node.js 服务或 Docker 容器),它们分别占用不同的端口(如 8080、3000)。难道我们要让用户记住 http://ip:8080 这样难看的地址吗?
显然不行。
这时候就需要用到 Nginx 反向代理。传统的 Nginx 配置对新手来说比较劝退,需要手动修改 nginx.conf,一不小心就会报 404 或 502。而 宝塔面板(BT Panel) 提供了可视化的配置界面,让我们能像搭积木一样轻松搞定反向代理和负载均衡。
本文将基于我的一次 Docker 实验,详细记录如何通过宝塔面板,将宿主机上的两个 Nginx 容器(nginx_web1、nginx_web2)通过反向代理整合成一个统一入口,并实现 加权轮询(Weight) 负载均衡。
无论你是运维新手,还是正在做 Docker 实验的学生,这篇实战笔记都能帮你少踩坑,快速上手。
二、实验环境
1️⃣ 硬件环境
- 云服务器:CentOS 7 操作系统
2️⃣ 软件环境
| 组件 | 版本/说明 |
|---|---|
| 操作系统 | CentOS 7 |
| 容器引擎 | Docker |
| Web 服务 | Nginx |
| 管理面板 | 宝塔面板 (BT Panel) |
3️⃣ 架构说明
本次实验采用 单宿主机 + 多容器 的架构,由宿主机 Nginx 充当反向代理与负载调度器,将请求分发给后端的两个 Docker 容器。
NGINX反向代理原理:

三、环境准备(宝塔 + Docker)
1️⃣ 安装宝塔面板
if [ -f /usr/bin/curl ]; then
curl -sSO https://download.bt.cn/install/install_panel.sh;
else
wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;
fi
bash install_panel.sh ed8484bec
2️⃣选择docker选项并编译安装

等待时间比较久别急
3️⃣ 配置 Docker 镜像源加速下载
为了提高 Docker 镜像的拉取速度(特别是在国内服务器上),需要配置国内镜像加速器。
执行以下命令编辑 Docker 配置文件:
vi /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
4️⃣ 清空宿主机 Nginx 默认首页文件
为了排除宝塔默认欢迎页面的干扰,确保后续反向代理实验的准确性,我们需要清空宿主机的 Nginx 默认首页。
操作步骤:
删除原有默认页面:
# 直接删除并创建空文件
rm -f /www/server/nginx/html/index.html
touch /www/server/nginx/html/index.html
四、Docker 部署两个后端 Nginx 容器
本节将通过 Docker 快速拉起两个 Nginx 容器,模拟后端业务节点,并通过修改默认首页内容来区分不同节点。
1️⃣ 拉取 Nginx 镜像
首先从 Docker Hub 拉取最新的 Nginx 镜像,并查看本地镜像列表。
docker pull nginx
docker images
2️⃣ 创建并配置 nginx_web1
创建第一个容器,映射宿主机 8080 端口到容器 80 端口。
docker run -p 8080:80 --name nginx_web1 -it nginx /bin/bash
#进入容器终端后,修改默认首页内容,用于标识节点:
echo "hello nginx_web1" > /usr/share/nginx/html/index.html
exit
3️⃣ 创建并配置 nginx_web2
创建第二个容器,映射宿主机 8081 端口到容器 80 端口。
docker run -p 8081:80 --name nginx_web2 -it nginx /bin/bash
#进入容器终端后,修改默认首页内容,用于标识节点:
echo "hello nginx_web2" > /usr/share/nginx/html/index.html
exit
注:使用 -it进入容器修改文件后,执行 exit会导致容器停止。这是为了方便实验演示,生产环境建议使用 -d后台运行并配合 -v挂载文件。
4️⃣ 启动容器并运行 Nginx 服务
由于使用 -it 参数创建后容器处于停止状态,需手动启动并后台运行 Nginx 服务。
#启动两个容器
docker start nginx_web1 nginx_web2
#在容器内后台启动 Nginx 进程
docker exec -d nginx_web1 service nginx start
docker exec -d nginx_web2 service nginx start
#确认容器运行状态
docker ps
五、宝塔配置 Nginx 负载均衡
为了让宿主机能够对外统一提供服务,并分发流量到后端两个 Docker 容器,我们需要在宝塔面板中配置 Nginx 的 upstream 模块。
1️⃣ 配置方式选择
有两种方式可以修改 Nginx 配置,任选其一即可:
| 方式 | 操作路径 | 适用场景 |
|---|---|---|
| 方式一(推荐) | 宝塔面板 → 软件商店 → Nginx → 配置修改 | 新手友好,不易因路径错误导致修改失败 |
| 方式二 | 命令行编辑 /www/server/nginx/conf/nginx.conf | 熟悉 Linux 运维,习惯使用 Vim 的用户 |
2️⃣ 添加负载均衡配置
在 http {} 代码块内(注意:不是 server {} 里面)添加以下配置:
#定义后端服务器集群,命名为 master
upstream master {
# 权重 weight 越大,被分配的请求越多
#注意:请将 192.168.150.10 替换为你服务器的实际内网 IP!
server 192.168.150.10:8080 weight=10;
server 192.168.150.10:8081 weight=20;
}
#定义虚拟主机
server{
listen 80;
server_name master;# 此处应与 upstream 名称对应或填写你的域名
location / {
# 转发请求到 upstream 集群
proxy_pass http://master;
# 传递客户端真实信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
3️⃣ 重载 Nginx 配置
配置保存后,必须重载 Nginx 使其生效,切勿直接重启,以免中断现有连接。
- 操作:宝塔面板 → Nginx → 重载配置(Reload)
4️⃣ 放行端口(关键步骤)
如果端口未放行,外部用户将无法访问服务。
🔹 宝塔面板防火墙
进入 宝塔面板 → 安全,放行以下端口:
| 端口 | 协议 | 备注 |
|---|---|---|
| 80 | TCP | HTTP 默认端口 |
| 8080 | TCP | 后端节点1 |
| 8081 | TCP | 后端节点2 |
宝塔防火墙/服务器安全放行 80、8080、8081 端口

六、功能验证
配置完成后,我们需要验证负载均衡是否生效,以及权重分配是否符合预期。
1️⃣ 访问测试
在浏览器中输入你的 服务器公网 IP 或绑定的域名(例如 http://your_server_ip)。
操作动作:
- 打开浏览器访问地址。
- 连续多次刷新页面(Ctrl + F5 强制刷新)。
2️⃣ 预期结果
由于我们在 upstream 中配置了权重,页面内容会交替变化,且出现频率不同:
| 页面显示内容 | 对应后端节点 | 权重值 | 预期出现概率 |
|---|---|---|---|
hello nginx_web1 | nginx_web1 (8080) | 10 | 较低 (约 33%) |
hello nginx_web2 | nginx_web2 (8081) | 20 | 较高 (约 67%) |
现象描述:
- 第一次刷新:显示
hello nginx_web1 - 第二次刷新:显示
hello nginx_web2 - 第三次刷新:显示
hello nginx_web2 - 第四次刷新:显示
hello nginx_web1 - …(以此类推)
📊 数据分析:因为
weight=20是weight=10的两倍,所以在大量请求下,nginx_web2接收到的访问量理论上会是nginx_web1的 2 倍。
3️⃣ 验证结论
通过多次刷新,页面能够按照权重比例交替显示不同内容,证明 Nginx 反向代理与加权轮询负载均衡配置成功。
七、常见问题与解决方案
在配置 Docker 和 Nginx 负载均衡的过程中,可能会遇到以下几个典型问题,请参考下表进行排查:
| 故障现象 | 原因 | 解决方案 |
|---|---|---|
| docker run 后容器停止 | 使用 -it 启动交互模式,执行 exit 会终止容器进程。 | 使用 docker start 容器名 重新启动容器。 |
| 外网无法访问端口 | 服务器防火墙(宝塔)或云服务商安全组未放行对应端口。 | 前往宝塔面板 -> 安全 -> 放行端口;同时检查云服务器控制台的入方向安全组规则。 |
| Nginx 重载失败 | 修改配置文件后存在语法错误。 | 执行 nginx -t 命令检查配置文件语法是否正确。 |
| 只访问单个节点 | 另一个容器未正常启动,或者负载均衡配置中的权重(weight)设置导致概率极低。 | 执行 docker ps 检查所有后端容器是否都处于 Up 状态。 |
八、核心知识点总结
通过本次实验,我们不仅完成了环境搭建,还验证了 Nginx 负载均衡的核心机制。以下是关键知识点复盘:
1️⃣ Weight 权重(加权轮询)
- 定义:
weight决定了后端节点被分配请求的概率。 - 规则:数值越大,接收的请求越多。
- 实验结论:
nginx_web1(weight=10)nginx_web2(weight=20)- 访问比例:理论值为 1 : 2,即每 3 次请求中,web2 会被访问 2 次。
2️⃣ 常用调度算法
除了加权轮询,Nginx 还支持多种调度策略,适用于不同业务场景:
| 算法 | 说明 | 适用场景 |
|---|---|---|
| 加权轮询 (default) | 按权重比例轮流分配请求 | 通用场景,服务器性能不均时 |
| ip_hash | 根据客户端 IP 计算 hash,固定访问某节点 | 解决 Session 共享问题 |
| least_conn | 优先分配给当前连接数最少的节点 | 请求处理时间长短不一的场景 |
| url_hash | 根据请求的 URL 进行 hash 分配 | 静态资源缓存,提高缓存命中率 |
3️⃣ proxy_set_header 的作用
在反向代理配置中,这一步骤至关重要,用于向后端服务器传递客户端的真实信息:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 目的:防止后端服务只能获取到代理服务器的 IP,而无法获取真实访客 IP。
- 价值:确保后端日志统计准确,便于安全审计和用户行为分析。
4️⃣ 容器数据持久化(重点)
问题:Docker 容器重启或重建后,内部的数据(如我们修改的 index.html)会丢失。
解决方案:使用 -v 参数进行目录挂载(Volume Mapping),将宿主机的目录映射到容器内。
九、总结与心得
本次实验通过 宝塔面板 + Docker + Nginx 的组合,成功搭建了一套基于 反向代理的负载均衡架构。相比于纯命令行的复杂配置,宝塔的可视化操作大大降低了运维门槛,而 Docker 则让我们能够快速克隆出多个后端业务节点。
🎯 实验成果
- 成功实现了 加权轮询(Weighted Round Robin) 策略,流量按
1:2的比例分发给后端容器。 - 掌握了
proxy_set_header等关键参数,确保了后端能获取真实用户 IP。 - 验证了 “单入口、多节点” 的高可用架构模式。
💡 避坑指南
- 端口放行是重中之重:很多时候配置对了但访问不通,多半是云服务器安全组或宝塔防火墙没开。
- 容器生命周期:使用
-it进入容器后,切记用exit退出会导致容器停止,需用docker start重启。 - 配置备份:修改 Nginx 配置前,建议先备份原文件或在宝塔中点击“保存并重载”,避免因手误导致服务瘫痪。
🚀 下一步计划
目前的配置仅适用于测试环境,在生产环境中,我们还需要考虑:
- HTTPS 证书配置(Let’s Encrypt)
- Nginx 健康检查(主动剔除故障节点)
- 动静分离(静态资源直接由 Nginx 处理,动态请求转发给容器)
如果你也在学习 Docker 或 Nginx 运维,希望这篇实战笔记能帮你少走弯路!如果有问题,欢迎在评论区交流讨论 。
&spm=1001.2101.3001.5002&articleId=161900709&d=1&t=3&u=ff875821b3ff4067a3c19ad3812dc9c8)
2578

被折叠的 条评论
为什么被折叠?



