4.2 反向代理与负载均衡


文档摘要

4.2 反向代理与负载均衡 本节摘要:反向代理是现代 httpd 最重要的角色之一——它站在后端应用前面,把请求转发过去、把响应带回来,顺路做 TLS 终结、压缩、缓存与流量分配。本节从最简单的 ProxyPass 起步,搭建带故障转移的多后端负载均衡,讲清轮询、最少连接、会话粘性三种调度策略的取舍,最后给出 502/503/504 三类代理故障的标准排查路径。 学习目标 阅读完本节,你应当能够: 写出最小可用的反向代理配置并理解 ProxyPass 与 Location 的关系; 配置多后端负载均衡器并解释故障转移行为; 按业务特征选择调度策略与会话粘性; 正确透传客户端真实地址等关键请求头; 按流程排查 502、503、504 故障。

4.2 反向代理与负载均衡

本节摘要:反向代理是现代 httpd 最重要的角色之一——它站在后端应用前面,把请求转发过去、把响应带回来,顺路做 TLS 终结、压缩、缓存与流量分配。本节从最简单的 ProxyPass 起步,搭建带故障转移的多后端负载均衡,讲清轮询、最少连接、会话粘性三种调度策略的取舍,最后给出 502/503/504 三类代理故障的标准排查路径。

学习目标

阅读完本节,你应当能够:

  1. 写出最小可用的反向代理配置并理解 ProxyPass 与 Location 的关系;
  2. 配置多后端负载均衡器并解释故障转移行为;
  3. 按业务特征选择调度策略与会话粘性;
  4. 正确透传客户端真实地址等关键请求头;
  5. 按流程排查 502、503、504 故障。

为什么要在后端前面放一台 httpd

现代 Web 应用的典型拓扑:浏览器 → httpd(80/443)→ 后端应用(Tomcat、Node、Python 服务,监听内网高端口)。httpd 在中间的价值有四:

TLS 终结:证书、握手、续期全在前端一台处理,后端集群不必逐台配证书。安全边界:后端只监听内网,攻击面收敛到一台前置机。路由与分流:按路径把不同前缀转给不同应用,一个域名下挂多个服务。流量治理:压缩、缓存、限速、灰度分流都在这一层做,后端专心业务。

最小配置(需要 proxy、proxy_http 模块):

<VirtualHost *:443> ServerName app.example.com SSLEngine on # ... 证书配置见第5章 ... # 一行代理:把 /api 下的一切转给后端 ProxyPass /api http://127.0.0.1:8080/api ProxyPassReverse /api http://127.0.0.1:8080/api </VirtualHost>

ProxyPass 定义"去程":URL 前缀到后端的映射。ProxyPassReverse 修"回程":后端如果返回带自身地址(127.0.0.1:8080)的重定向头,前端把它改写回对外域名,用户不会看见内网地址。两行成对出现是肌肉记忆。

一个容易忽略却必做的配置——透传客户端真实地址。默认情况下后端看到的来源 IP 是前置机 IP,日志统计、风控、限频全部失真。透传靠请求头:

ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" # proxy 模块会自动附加 X-Forwarded-For 记录客户端IP链

后端应用读 X-Forwarded-For(注意取"链"里第一个才是真实客户端,前面有多个代理时要配置可信跳数)与 X-Forwarded-Proto。漏掉这一步,后端生成的绝对链接可能错误地退化成 http,产生混合内容告警。

从单后端到负载均衡器

单后端没有可用性。把 ProxyPass 的目标换成一个"均衡器",就得到多后端池:

<Proxy balancer://appcluster> BalancerMember http://10.0.1.11:8080 loadfactor=1 BalancerMember http://10.0.1.12:8080 loadfactor=1 BalancerMember http://10.0.1.13:8080 loadfactor=2 # 第三台机器配置高,分它双倍流量 </Proxy> ProxyPass /api balancer://appcluster/api ProxyPassReverse /api balancer://appcluster/api

loadfactor 实现加权分配。故障转移是自动的:某成员连接失败,请求转给其余成员(默认 lbmethod 策略下)。验证方式很朴素——手动停掉一台后端,用循环请求观察是否全部成功:

for i in $(seq 1 20); do curl -s -o /dev/null -w "%{http_code} " https://app.example.com/api/ping done; echo # 期望输出全是 200,说明故障转移在工作

三种调度策略(lbmethod)的取舍:

策略 分配逻辑 适合
byrequests(默认) 按请求数轮转,可加权 请求耗时相近的 API
bytraffic 按流量字节数 文件下载类,避免大文件压垮一台
bybusyness 给当前最闲的后端 请求耗时长短差异大的混合负载

会话粘性:登录态存在后端内存会话里的老应用,同一用户必须始终打到同一台,否则不断被踢回登录页。开粘性路由:

Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy balancer://appcluster> BalancerMember http://10.0.1.11:8080 route=member1 BalancerMember http://10.0.1.12:8080 route=member2 ProxySet stickysession=ROUTEID </Proxy>

原理:首次响应种一个标记后端的 Cookie,后续请求带 Cookie 来,均衡器按标记送回原机。要认清粘性的代价——它削弱均衡(一台被"粘住"的流量下不掉),而且后端宕机时粘在上面的用户会话丢失。新应用应把会话外置到共享存储(Redis 一类)而不是依赖粘性,粘性只是老系统的兼容手段。

健康检查:别把流量发给死人

默认的"被动"故障转移要等真实请求失败才切走,用户体验是"偶尔慢一下"。主动健康检查定期探测后端状态(mod_proxy_hcheck 模块,配在 ProxySet 或 BalancerMember 上):

<Proxy balancer://appcluster> BalancerMember http://10.0.1.11:8080 hcmethod=GET hcuri=/health hcfails=2 hcinterval=10 BalancerMember http://10.0.1.12:8080 hcmethod=GET hcuri=/health hcfails=2 hcinterval=10 </Proxy>

含义:每 10 秒 GET 一次后端的健康端点,连续 2 次失败即摘除,恢复成功自动回池。后端的健康端点要检查真实依赖——只返回"进程活着"不查数据库的端点,会在数据库挂掉时继续"健康"地接收流量。

均衡器的运行状态可以可视化:启用 mod_status 的 balancer 视图(用浏览器访问内置状态页并开启扩展标记),能看到每个成员的请求数、失败数、当前状态——排障时一眼定位哪台后端在拖后腿。

**注意一个高频坑:代理的 Timeout 默认值偏长,后端卡死时前端线程被占着陪等,event 模型也扛不住大面积卡死。给代理场景显式设置 ProxyTimeout 30 与连接复用的 retry=30(失败成员的冷静期),让故障快速止损而不是拖死全家。

502/503/504:代理故障三兄弟

这三类状态码占代理故障的九成,各有明确含义与排查方向:

502 Bad Gateway:后端返回了无效响应或连接被拒。方向:后端进程活着吗(curl 127.0.0.1:8080/health 直接打后端)、端口对吗、后端是否把前置机请求当非法(Host 头不匹配,ProxyPreserveHost 检查一下)。

503 Service Unavailable:均衡器没有可用成员。方向:所有成员都被健康检查摘除了?刚 reload 后配置错误?错误日志里通常直书"no viable backend"。

504 Gateway Timeout:后端活着但太慢,超过 ProxyTimeout。方向:是普遍慢(后端容量不足)还是个别接口慢(慢查询、外部依赖),后端自身日志与应用指标给答案。

图 4-2 代理请求流转与故障定位

图 4-2 代理请求流转与故障定位

本节要点回顾

  • 前置四大价值:TLS 终结、安全边界、路由分流、流量治理;
  • 两行成对:ProxyPass 去程、ProxyPassReverse 修回程重定向;
  • 透传三件套:X-Forwarded-For、X-Forwarded-Proto、ProxyPreserveHost,漏一个后端就"失明";
  • 调度三策略:按请求、按流量、按忙闲,按请求耗时的方差选;
  • 粘性是债:会话外置才是正路,粘性只救老系统;
  • 主动健康检查:hcmethod 配真实依赖探测端点,快速摘除快速回池;
  • 故障三兄弟:502 连不上、503 没成员、504 后端慢,各有固定排查路径。

💡 一句话记住本节:反向代理的本质是"替用户跑腿"——跑腿的质量取决于你把地址、身份、超时这三件事交代得多清楚。

下一节看旅程生成区的另一条线:动态内容在本机如何生成。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U