文章目录
- 一、前言
- 二、实验环境
- 三、环境准备(宝塔 + Docker)
- 四、Docker 部署两个后端 Nginx 容器
- 五、宝塔配置 Nginx 负载均衡
- 六、功能验证
- 七、常见问题与解决方案
- 八、核心知识点总结
- 九、总结与心得
一、前言
在搭建个人博客或部署微服务时,我们经常会遇到这样一个问题:服务器上跑了多个应用(比如 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];thencurl-sSOhttps://download.bt.cn/install/install_panel.sh;elsewget-Oinstall_panel.sh https://download.bt.cn/install/install_panel.sh;fibashinstall_panel.sh ed8484bec2️⃣选择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.htmltouch/www/server/nginx/html/index.html四、Docker 部署两个后端 Nginx 容器
本节将通过 Docker 快速拉起两个 Nginx 容器,模拟后端业务节点,并通过修改默认首页内容来区分不同节点。
1️⃣拉取 Nginx 镜像
首先从 Docker Hub 拉取最新的 Nginx 镜像,并查看本地镜像列表。
dockerpull nginxdockerimages2️⃣创建并配置 nginx_web1
创建第一个容器,映射宿主机8080端口到容器80端口。
dockerrun-p8080:80--namenginx_web1-itnginx /bin/bash#进入容器终端后,修改默认首页内容,用于标识节点:echo"hello nginx_web1">/usr/share/nginx/html/index.htmlexit3️⃣创建并配置 nginx_web2
创建第二个容器,映射宿主机8081端口到容器80端口。
dockerrun-p8081:80--namenginx_web2-itnginx /bin/bash#进入容器终端后,修改默认首页内容,用于标识节点:echo"hello nginx_web2">/usr/share/nginx/html/index.htmlexit注:使用 -it进入容器修改文件后,执行 exit会导致容器停止。这是为了方便实验演示,生产环境建议使用 -d后台运行并配合 -v挂载文件。
4️⃣启动容器并运行 Nginx 服务
由于使用-it参数创建后容器处于停止状态,需手动启动并后台运行 Nginx 服务。
#启动两个容器dockerstart nginx_web1 nginx_web2#在容器内后台启动 Nginx 进程dockerexec-dnginx_web1servicenginx startdockerexec-dnginx_web2servicenginx start#确认容器运行状态dockerps五、宝塔配置 Nginx 负载均衡
为了让宿主机能够对外统一提供服务,并分发流量到后端两个 Docker 容器,我们需要在宝塔面板中配置 Nginx 的upstream模块。
1️⃣配置方式选择
有两种方式可以修改 Nginx 配置,任选其一即可:
| 方式 | 操作路径 | 适用场景 |
|---|---|---|
| 方式一(推荐) | 宝塔面板 → 软件商店 → Nginx →配置修改 | 新手友好,不易因路径错误导致修改失败 |
| 方式二 | 命令行编辑/www/server/nginx/conf/nginx.conf | 熟悉 Linux 运维,习惯使用 Vim 的用户 |
2️⃣添加负载均衡配置
在http {}代码块内(注意:不是server {}里面)添加以下配置:
#定义后端服务器集群,命名为 masterupstream master{# 权重 weight 越大,被分配的请求越多#注意:请将 192.168.150.10 替换为你服务器的实际内网 IP!server192.168.150.10:8080weight=10;server192.168.150.10:8081weight=20;}#定义虚拟主机server{listen80;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 运维,希望这篇实战笔记能帮你少走弯路!如果有问题,欢迎在评论区交流讨论 。