Nginx 反向代理与负载均衡实战(基于陶辉《深入理解 Nginx》第三章)

发布时间:2026/9/16 5:59:16

Nginx 反向代理与负载均衡实战(基于陶辉《深入理解 Nginx》第三章) Nginx 反向代理与负载均衡实战基于陶辉《深入理解 Nginx》第三章本文所有命令输出均来自两台真实云服务器Ubuntu 24.04.4 / nginx 1.24.0的现场回显未做任何编造。拓扑目标一台代理层把流量按多种策略转发给上游的多个后端并具备故障自动转移能力。一、实验拓扑公网 / 客户端 │ ┌────────▼────────┐ │ 代理层 PROXY │ 139.9.***.*** (公网) │ 192.168.0.149 │ nginx 1.24.0 │ upstream │ │ proxy_pass │ └────────┬─────────┘ 内网 192.168.0.xVPC 互通走内网不占公网带宽 │ ┌────────▼────────┐ │ 上游层 UPSTREAM │ 119.3.***.*** (公网) │ 192.168.0.113 │ nginx 1.24.0 │ 3 个后端: │ │ 8081/8082/8083 │ └──────────────────┘代理层承担「反向代理 负载均衡」对外只暴露 80/443内网回源走192.168.0.113。上游层用 3 个独立server块模拟 3 台应用服务器各自返回可区分的身份头X-Backend方便观察分发结果。二、环境准备两台机器两台均用发行版自带的 nginxapt 安装无需编译版本与运行状态如下$ nginx-vnginx version: nginx/1.24.0(Ubuntu)$ systemctl is-active nginx active $ ss-ltn|grep:80LISTEN05110.0.0.0:800.0.0.0:* LISTEN0511[::]:80[::]:*上游层部署 3 个后端/etc/nginx/conf.d/backends.conf节选server { listen 8081; server_name _; default_type text/plain; add_header X-Backend backend-8081; location / { return 200 backend-8081 served at $time_local\n; } } # 8082 / 8083 结构相同仅端口与标识不同本地验证三个后端均可独立响应$curl-s-ihttp://127.0.0.1:8081/|head-8HTTP/1.1200OK Server: nginx/1.24.0(Ubuntu)Content-Type: text/plain X-Backend: backend-8081 $curl-shttp://127.0.0.1:8082/api/health OK backend-8082 $ ss-ltn|grep-E:808[123]LISTEN05110.0.0.0:80810.0.0.0:* LISTEN05110.0.0.0:80830.0.0.0:* LISTEN05110.0.0.0:80820.0.0.0:*代理层先确认能通过内网访问到上游这是生产最佳实践回源走内网省公网带宽、低延迟$curl-s-ihttp://192.168.0.113:8081/|head-6HTTP/1.1200OK Server: nginx/1.24.0(Ubuntu)Content-Type: text/plain Content-Length:50Connection: keep-alive三、反向代理基础proxy_pass反向代理的核心只有一行proxy_pass它把客户端请求转发给 upstream 定义的后端组# /etc/nginx/conf.d/proxy_upstreams.conf upstream backend_rr { zone backend_rr 64k; server 192.168.0.113:8081; server 192.168.0.113:8082; server 192.168.0.113:8083; }# /etc/nginx/conf.d/proxy_lb.conf server { listen 80; server_name _; add_header X-Upstream $upstream_addr always; # 透出实际选中的后端 location / { proxy_pass http://backend_rr; 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; } }proxy_set_header三件套非常关键X-Real-IP/X-Forwarded-For把真实客户端 IP 透传给后端否则后端access.log里全是代理 IP。Host $host保留原始 Host避免后端因 Host 不匹配而走默认站点。X-Forwarded-Proto告知后端原始协议http/https对生成重定向链接、校验安全 cookie 很重要。从公网直接访问代理的 80 端口请求被转发到内网后端并回传身份头$curl-s-ihttp://139.9.***.***/|grep-iEX-Backend|X-Upstream|HTTP/HTTP/1.1200OK X-Backend: backend-8081 X-Upstream:192.168.0.113:8081X-Backend来自上游后端X-Upstream来自代理层$upstream_addr——两个头合起来一条请求从「客户端 → 代理 → 哪个后端」的链路就一目了然。四、负载均衡算法逐一验证代理层同时开了 4 个端口分别绑定不同算法的 upstream便于横向对比端口算法upstream80默认轮询 round-robinbackend_rr8091加权轮询 weightedbackend_weighted8092ip_hash 一致性哈希backend_iphash8093最少连接 least_connbackend_leastconn⚠️踩坑与最佳实践最开始我没有给upstream加zone指令结果多 worker 下轮询状态各自独立连续 9 次请求里 8 次都打到了backend-8081--1-- X-Backend: backend-8081 / X-Upstream: 192.168.0.113:8081 ...2~8 同样 --9-- X-Backend: backend-8082 / X-Upstream: 192.168.0.113:8082加上zone backend_rr 64k;后把节点状态放进共享内存分发立刻均衡见下。生产环境强烈建议所有 upstream 都加zone它还能支持运行时增删节点upstream_conf。1) 默认轮询round-robin$foriin$(seq130);docurl-s-ihttp://127.0.0.1:80/|grep-iX-Backend|tr-d\r;done|sort|uniq-c10X-Backend: backend-808110X-Backend: backend-808210X-Backend: backend-8083三个后端严格 1:1:1符合 round-robin 的加权轮询默认权重相等。2) 加权轮询weightupstream backend_weighted { zone backend_weighted 64k; server 192.168.0.113:8081 weight3; server 192.168.0.113:8082 weight1; server 192.168.0.113:8083 weight1; }$foriin$(seq120);docurl-s-ihttp://127.0.0.1:8091/|grep-iX-Backend|tr-d\r;done|sort|uniq-c12X-Backend: backend-80814X-Backend: backend-80824X-Backend: backend-808312:4:4 3:1:1与配置权重完全吻合。当某台机器性能好、或某实例权重高时用weight把更多流量分给它。3) 最少连接least_connupstream backend_leastconn { zone backend_leastconn 64k; least_conn; server 192.168.0.113:8081; server 192.168.0.113:8082; server 192.168.0.113:8083; }$foriin$(seq130);docurl-s-ihttp://127.0.0.1:8093/|grep-iX-Backend|tr-d\r;done|sort|uniq-c10X-Backend: backend-808110X-Backend: backend-808210X-Backend: backend-8083本例请求都极轻量连接数始终为 0所以退化为均匀分发。least_conn的真正价值在「请求耗时不均」的场景谁最闲分谁避免慢请求把某台机器堆满。它同样常与zone搭配。4) ip_hash 一致性哈希upstream backend_iphash { zone backend_iphash 64k; ip_hash; server 192.168.0.113:8081; server 192.168.0.113:8082; server 192.168.0.113:8083; }$foriin1234;docurl-s-ihttp://127.0.0.1:8092/|grep-iX-Backend|tr-d\r;doneX-Backend: backend-8083 X-Backend: backend-8083 X-Backend: backend-8083 X-Backend: backend-8083同一客户端 IP 始终落到同一后端——这正是「会话保持 / 粘性」的需求场景如未做分布式 Session 时让用户总是命中同一台缓存了状态的应用。注意ip_hash是按$remote_addr哈希若前端还有 CDN/反向代理需配合X-Forwarded-For的real_ip模块才能拿到真实客户端 IP。五、故障自动转移failover负载均衡不只是「分发」更是「容错」。当某后端不可达时Nginx 默认通过proxy_next_upstream把请求重试到下一个健康节点。我们在上游层用iptables把 8082 端口「拒绝」掉模拟该后端宕机$ iptables-IINPUT-ptcp--dport8082-jREJECT;echoadded added $ iptables-LINPUT-n|grep8082REJECT6--0.0.0.0/00.0.0.0/0 tcp dpt:8082 reject-with icmp-port-unreachable此时从代理层连续请求 12 次$foriin$(seq112);docurl-s-ihttp://127.0.0.1:80/|grep-iX-Backend|tr-d\r;done|sort|uniq-c6X-Backend: backend-80816X-Backend: backend-8083死掉的8082一次都没出现流量被自动切到8081与8083。恢复后移除规则$ iptables-DINPUT-ptcp--dport8082-jREJECT;echoremoved removed $ iptables-LINPUT-n|grep8082||echonone none说明开源版 Nginx 没有「主动健康检查」health_check需商业版 Nginx Plus。这里的 failover 依赖被动健康检查——只有当连接/超时/返回错误proxy_next_upstream默认的error timeout发生时才换节点。生产环境可结合max_fails/fail_timeout让节点被「熔断」一段时间或用第三方模块做主动探活。六、小结反向代理proxy_passproxy_set_header透传 Host / 真实 IP / 协议即可回源优先走内网。负载均衡round-robin 默认均分weight调权重least_conn按连接数选闲ip_hash做会话保持。四者都在upstream块内声明。两个关键经验upstream务必加zone—— 否则多 worker 下分发会严重偏斜实测 9 次里 8 次打同一台。failover 默认开启proxy_next_upstream但属于被动健康检查高可用需额外探活机制。下一篇我们将基于这套拓扑继续实战反向代理缓存与HTTPS HTTP/2。
延伸阅读

更多相关文章

2026/9/16 16:20:23

面向对象与异常处理:从自动咖啡机看 Python 类设计

面向对象与异常处理:从自动咖啡机看 Python 类设计 一、背景引入 学会了文件、函数和装饰器,你已经能写出「可复用」的代码。但当程序需要长期维护一组相关联的状态——比如一台咖啡机的豆量、水量、奶量,以及「待机 / 制作中 / 完成」的状态…

2026/9/17 2:53:56

企业级AI Agent平台建设方案:从架构分层到工程治理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 2:53:56

HC/LC/AC/FT四种经典显著性检测算法C++实现

简介:本资源是一套面向计算机视觉初学者与研究者的显著性检测算法实践代码包,聚焦HC、LC、AC、FT四类经典方法,解决图像中关键区域自动定位问题,适用于图像摘要、目标检测预处理、交互式编辑等实际场景。压缩包共16个文件&#xf…

2026/9/17 2:53:56

中国九大农业区SHP数据处理:坐标系统、投影转换与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 2:53:56

从TOPS到Token/sec:AI芯片算力指标深度解析与实测指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 2:48:56

六轮DES差分分析:用C++实现S盒差分表与子密钥投票恢复

简介:基于C的六轮DES算法差分分析实现,面向密码学课程设计与差分密码分析入门者,完整呈现选择明文攻击的工程化落地流程。代码按模块划分为四部分:6轮DES加解密模块用于产生明密文对与最终验证;差分分析表生成模块用于…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码