当前位置: 首页 > news >正文

【第三章】14-常用模块2-ngx_http_proxy_module

什么是代理?代理是作为中间层,作用于上下游两端。将下游的“请求”转移提交到上游,将上游的“响应”提交给下游。代理不仅在设计模式等程序设计中有比较广泛的使用,同时在大型的系统工程中使用也比较广泛,在web服务器领域,代理出现的频率也是很高的。

目录

一、 ngx_http_proxy_module模块介绍

1.1 代理的本质与应用场景:从中间层到工程实践

1.1.1 重新定义“代理”:不只是桥梁

1.1.2 正向代理 vs 反向代理:穿透迷雾的对比

1.1.3 反向代理的不可替代性:

1.1.4 Nginx代理体系:proxy与upstream的默契配合

1.1.5 代理链路的全流程解析

1.1.6  避免常见误区:代理的进阶认知

1.2  ngx_http_proxy_module参数详解

参数1:proxy_set_header

参数2:proxy_buffering on;

参数3:proxy_buffer_size 4k;

参数4:proxy_buffers 8 4k;

参数5:proxy_busy_buffer_size 16k;

参数6: proxy_temp_path

参数7: proxy_max_temp_file_size

1.3 proxy_pass 代理七层转发

1.4 proxy_pass时url末尾带“/”与不带“/”的区别

二、代理层cache与处理cache

2.1 代理层的proxy_cache机制

2.2 代理层的proxy_cache应用


一、 ngx_http_proxy_module模块介绍

地址:Module ngx_http_proxy_module

1.1 代理的本质与应用场景:从中间层到工程实践

1.1.1 重新定义“代理”:不只是桥梁

        在分布式架构中,代理(Proxy)常被比作“中间人”,但其核心价值远不止传递数据。它的核心使命是解耦上下游:

  • 对下游:隐藏上游的拓扑细节(如服务器IP、负载策略),提供统一的接入入口。

  • 对上游:过滤非法请求(如DDoS攻击)、预处理数据(如压缩/加密),减轻业务服务器压力。

PS: 上游与下游的解释

基本概念

  • 下游(Downstream):请求的发起方或数据接收端,通常是更靠近客户端的一侧。

  • 上游(Upstream):请求的接收方或数据提供端,通常是更靠近服务端的一侧。
    核心规则:数据流动方向决定上下游关系,下游是“索取者”,上游是“提供者”。

反向代理中的上下游,在典型Nginx反向代理场景中:

客户端(下游) → Nginx(上游) → 后端服务器(更上游)
  • 客户端视角:Nginx是上游(直接交互的对象)。

  • Nginx视角:后端服务器是上游(实际处理请求的服务)。

  • 后端服务器视角:Nginx是下游(请求来源)。


1.1.2 正向代理 vs 反向代理:穿透迷雾的对比

许多资料混淆二者的差异,关键在于视角和场景:

维度

正向代理

反向代理

使用角色

客户端主动配置(如浏览器代理)

服务端部署,客户端无感知

核心目的

突破访问限制(如科学上网)

负载均衡、安全防护、缓存加速

典型场景

企业内网代理、爬虫IP池

Nginx网关、API Gateway

流量方向

集中客户端分散请求 → 统一出口

分散客户端请求 → 集中入口处理

1.1.3 反向代理的不可替代性:

  • 安全性:屏蔽真实服务器IP,防止直接暴露于公网。

  • 扩展性:通过横向扩展代理节点,轻松应对高并发。

  • 灵活性:动态路由、A/B测试、灰度发布等高级功能的基础。


1.1.4 Nginx代理体系:proxy与upstream的默契配合

Nginx的代理能力由两大模块协同实现:

1) proxy模块:协议适配与流量治理

  • 核心职责:

    • 修改请求头(如X-Forwarded-For传递真实客户端IP)

    • 响应内容处理(如Gzip压缩、SSL证书卸载)

    • 流量控制(限速、缓冲区优化、超时熔断)

  • 关键配置示例:

    location /api/ {
        proxy_pass http://backend;  # 请求转发
        proxy_set_header Host $host;  # 透传原始域名
        proxy_read_timeout 5s;       # 防止慢请求阻塞
        proxy_buffers 8 16k;         # 内存缓冲区优化
        proxy_http_version 1.1;      # 强制使用HTTP长连接
    }

2) upstream模块:连接池与负载均衡

  • 核心职责:

    • 维护后端服务器池(健康检查、故障转移)

    • 负载均衡算法(轮询、权重、IP Hash等)

    • 连接复用(Keepalive优化,降低TCP握手开销)

  • 高阶用法:

    upstream backend {
        zone backend_zone 64k;     # 共享内存区,统计状态
        server 10.0.1.1:8080 max_fails=3;  # 自动剔除故障节点
        server 10.0.1.2:8080 backup;       # 备用服务器
        least_conn;                # 最少连接数策略
        keepalive 32;              # 连接池复用长链接
    }

1.1.5 代理链路的全流程解析

当Nginx处理一个反向代理请求时,实际经历了多个阶段的精细化控制:

  • 请求拦截:通过location匹配URL规则(如按路径或域名分流)。

  • 上游选择:从upstream池中按策略选取目标服务器。

  • 请求重写:修改请求头、URL路径(如rewrite规则)。

  • 数据中转:双向流式传输数据,支持零拷贝优化。

  • 响应处理:过滤敏感头、压缩内容、记录日志。

  • 异常熔断:超时、502错误自动重试或降级。


1.1.6  避免常见误区:代理的进阶认知

  • 代理≠性能瓶颈:通过内核级优化(如Linux的sendfile机制),Nginx的代理吞吐可达百万QPS。

  • 代理≠单向透传:可通过sub_filter修改响应内容,实现动态内容替换。

  • 代理≠仅限HTTP:Nginx的stream模块支持四层TCP/UDP代理(如数据库、游戏服务器)。

官网地址见:Module ngx_http_proxy_module

1.2  ngx_http_proxy_module参数详解

设置背景:

  • 客户端:192.168.0.63 访问 www.51xue.com

  • 代理层:192.168.0.64 配置 www.51xue.com转发到业务层的www.51xuebak.com

  • 业务层:192.168.0.65 配置 www.51xuebak.com并处理请求到后端层

  • 后端层:192.168.0.66 配置mysql集群

语法格式:

  • 作用:proxy_set_header是用来设置请求头的,设置了请求头后,后端服务器就可以获取到这些变量值。

  • 语法:proxy_set_header field value;

    • field :为要更改的项目,也可以理解为变量的名字,比如host

    • value :为变量的值

1.2.1 请求头重写:proxy_set_header的攻防博弈

proxy_set_header 是代理流量治理的「指纹修改器」,它决定了后端如何感知客户端身份。以下通过渗透测试场景解析其深层作用:

1.2.2 基础身份伪装:host与host与proxy_host

  • 场景:隐藏真实业务域名,防止被扫描工具识别

    location / {
        proxy_pass http://192.168.0.65;  # 直连IP,不暴露域名
        proxy_set_header Host www.mirr.com;  # 伪装域名
    }
    • 攻击者视角:只能看到www.mirr.com,无法关联真实业务www.51xuebak.com

    • 防御价值:增加黑产逆向工程成本,阻断基于域名的漏洞扫描

1.2.3 多租户隔离:$http_host的精准路由

当Nginx代理多个租户服务时:

server {
    listen 80;
    server_name tenant1.com;
    proxy_set_header Host $http_host;  # 透传原始域名
    proxy_pass http://backend;
}

server {
    listen 80;
    server_name tenant2.com;
    proxy_set_header Host $http_host;
    proxy_pass http://backend; 
}
  • 后端服务:通过Host头区分租户,实现单集群多域名隔离,比如你请求的是tenant1.com,就自动匹配到第一个server下。

  • 性能优势:避免为每个租户启动独立进程。

1.2.4  IP溯源体系:X-Forwarded-For的信任链构建

多层代理下的真实IP提取算法:

def get_real_ip(xff_header):
    ips = xff_header.split(', ')
    return ips[0] if len(ips) > 0 else None  # 首段为真实客户端IP
  • 安全威胁:若首段IP可伪造,可能导致IP欺骗

  • 加固方案

    set_real_ip_from 192.168.0.0/16;  # 只信任内网代理
    real_ip_header X-Forwarded-For;  
    real_ip_recursive on;              # 跳过可信代理IP

1.2.5  缓冲机制:proxy_buffer的性能生死线

缓冲配置不当可直接导致吞吐量雪崩,通过Linux内核参数优化突破瓶颈:

1) 缓冲区的「三区两界」模型
  • Header区(proxy_buffer_size):存储响应头,建议4K对齐(匹配SSD块大小)

  • Body区(proxy_buffers):环形缓冲队列,推荐8×4K(适配HTTP平均包大小)

  • Busy区(proxy_busy_buffer_size):冲刷阈值,建议≥16K(减少内核态切换)

2) 零拷贝优化:sendfile与buffer的化学反应

启用内核级零拷贝:

proxy_buffering on; 
sendfile on;         # 绕过用户空间,直接从页缓存发送
  • 性能收益:减少CPU拷贝次数,提升静态资源传输效率40%

  • 适用场景:大文件下载、视频流传输

1.2.6 临时文件黑洞:proxy_temp的容灾设计

临时文件是代理服务的「阿喀琉斯之踵」,需从架构层面规避风险:

1)多级存储隔离
proxy_temp_path /dev/shm/nginx_temp 1 2;  # 内存盘存储活跃文件
proxy_max_temp_file_size 2G;               # 防磁盘写满
proxy_temp_file_write_size 16k;            # 匹配SSD最佳写入单元
  • 内存盘优势:I/O速度比SSD快100倍,系统重启自动清理

  • 兜底方案:Crontab定时清理旧文件

    */30 * * * * find /dev/shm/nginx_temp -type f -mmin +30 -delete
2)故障注入测试
  • Case 1:磁盘空间耗尽 → 触发499日志并返回503状态码

  • Case 2:文件权限错误 → 通过SELinux沙盒自动修复

  • 防御策略

    proxy_temp_path /var/nginx_temp 1 2;
    error_page 500 502 503 504 =503 @failsafe;
    location @failsafe {
        return 503 "Service Degraded";
    }

1.3 proxy_pass 代理七层转发

公共代理参数文件:在跟nginx.conf配置文件同一目录下,建立一个proxy.conf文件,添加以下信息:

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 90;
proxy_send_time 90;
proxy_read_time 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64;
  • 然后再nginx.conf文件中包含proxy.conf文件进来:

server {
    listen 80;
    server_name ceshi1.10jqka.com.cn;
    root /var/www/html;
    proxy_ignore_client_abort on;
    access_log logs/ceshi1.access.log main;
    error_log logs/ceshi1.error.log notice;

    location = /break {
        rewrite ^/break/(.*) /test/$1 break;
        proxy_set_header Via "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://192.168.205.187/last/$1;
    }

    location ^~ /last/ {
        rewrite ^/last/(.*) /test/$1 last;
        proxy_set_header Via "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://www.ceshi2.com/$1;
    }
}

1.4 Nginx路径拼接规则:proxy_pass斜杠的「蝴蝶效应」

1.4.1 本质原理:URI的三种拼接模式

Nginx处理proxy_pass路径时,根据目标URL是否含URI,分为三种处理策略:

proxy_pass格式匹配模式路径处理规则
http://backend不含URI透传客户端完整路径
http://backend/含URI(根路径)删除location匹配部分,拼接剩余路径
http://backend/api含URI(非根路径)同上,但保留自定义前缀

1.4.2  斜杠触发「路径手术」的底层逻辑

1) 规则公式
代理目标URI = proxy_pass的URI部分 + (客户端URI - location匹配部分)
2) 核心代码逻辑(伪代码)
def process_proxy_pass(client_uri, location_match, proxy_pass_uri):
    if proxy_pass_uri.endswith('/'):
        # 精确切除location匹配部分
        cut_length = len(location_match)
        return proxy_pass_uri + client_uri[cut_length:]
    else:
        # 全量透传(含location匹配部分)
        return proxy_pass_uri + client_uri

1.4.3  四象限分析:斜杠的排列组合

假设客户端请求:http://nginx-host/test/tes.jsp

1) 象限1:location带斜杠 & proxy_pass带斜杠
location ^~ /test/ {        # 匹配部分:/test/
    proxy_pass http://backend/server/;  # 目标URI:/server/
}

代理路径:
/server/ + (tes.jsp) = http://backend/server/tes.jsp
:'/server/ + (tes.jsp) = http://backend/server/tes

2) 象限2:location无斜杠 & proxy_pass带斜杠
location ^~ /test {         # 匹配部分:/test
    proxy_pass http://backend/server/;  # 目标URI:/server/
}

代理路径
/server/ + (/tes.jsp) = http://backend/server//tes.jsp
(双斜杠可能导致后端路由异常)

3) 象限3:location带斜杠 & proxy_pass无斜杠
location ^~ /test/ {        # 匹配部分:/test/
    proxy_pass http://backend;  # 目标URI:空
}

代理路径
空 + (tes.jsp) = http://backend/test/tes.jsp
(透传原始路径,可能暴露内部结构)

4) 象限4:location无斜杠 & proxy_pass无斜杠
location ^~ /test {         # 匹配部分:/test
    proxy_pass http://backend;  # 目标URI:空
}

代理路径
空 + (/test/tes.jsp) = http://backend/test/tes.jsp


1.4.4  高级调试:抓包验证路径传递

1) tcpdump抓包命令
tcpdump -i eth0 -A -s 0 'port 8080' | grep "GET /"
2) 测试案例对比
场景预期路径实际抓包结果
象限2配置/server//tes.jspGET //tes.jsp HTTP/1.1
象限3配置/test/tes.jsp /测试/GET /test/tes.jsp HTTP/1.1
获取 /test/tes.jsp HTTP/1.1

总结:斜杠的「四要四不要」

不要
保持location与proxy_pass斜杠一致混合使用有无斜杠配置
用rewrite标准化路径依赖后端容忍异常路径
开启merge_slashes优化允许双斜杠出现在关键路径
定期扫描access_log验证忽视HTTP 400类错误日志

通过理解路径拼接的量子化特性,可避免90%的代理配置故障。

二、代理层cache与处理cache

2.1 代理层的proxy_cache机制

  • proxy_cache和fastcgi_cache构成了Nginx的缓存。

  • proxy_cache主要用于反向代理时,对后端内容源服务器进行缓存,可能是任何内容,包括静态的和动态,缓存减少了nginx与后端通信的次数,节省了传输时间和后端宽带;

  • fastcgi_cache在下一章节说明。

  • 涉及到的其他模块

    • 清除缓存模块:ngx_cache_pure

    • 扩展包下载地址:FRiCKLE Labs / nginx / ngx_cache_purge

2.2 代理层的proxy_cache的应用

http {
    proxy_temp_path /memdisk/proxy/proxy_dir;
    proxy_cache_path /memdisk/proxy levels=1:2 keys_zone=cache_proxy:1024m inactive=15m max_size=8168m;
    server {
        listen 80;
        server_name ceshi1.10jqka.com.cn;
        root /var/www/html;
        proxy_ignore_client_abort on;
        access_log logs/ceshi1.access.log main;
       error_log logs/ceshi1.error.log notice;
   
        location @fetch {
            internal;
            #proxy_next_upstream error timeout invalid_header http_502;
            #proxy_next_upstream_timeout 10;
            proxy_cache cache_proxy;
            proxy_cache_key $uri$is_args$args;
            proxy_cache_valid 200 2m;
            proxy_cache_use_stale error timeout invalid_header http_500 http_502;
            proxy_set_header Host stock.10jqka.com.cn;
            proxy_pass http://front_server;
        }
    }
}

2.2.1 缓存清理

  • 浏览图片文件:http://www.osyunwei.com/images/nopic.gif

  • 清除这个文件缓存:http://www.osyunwei.com/purge/images/nopic.gif

  • 提示:Successful purge,缓存文件清除成功,如果这个文件没有被缓存过,则提示:404 Not Found

备注:

  • purge是ngx_cache_pure 模块指令

  • images/nopic.gif 是要清除的缓存文件URL路径

2.2.2  proxy_cache_path的引用介绍

1) proxy_temp_path:缓存构建的「临时车间」
proxy_temp_path /memdisk/proxy/proxy_dir;
1.1) 核心作用

当Nginx从上游服务器接收响应时,若响应数据无法直接写入缓存(如大文件分块传输或缓存未就绪),会先存入临时目录,待完整接收后再原子化移动到缓存区。

1.2) 参数详解
  • 路径设计/memdisk/proxy/proxy_dir

    • /memdisk:通常为内存盘挂载点(如tmpfs),利用内存I/O加速临时文件操作

    • 三级目录结构:避免单目录文件数过多引发inode竞争

  • 未显式配置的参数

    • levels:默认无层级,适用于高频写入场景

    • use_temp_path:默认开启,需结合proxy_cache_pathuse_temp_path调优

1.3) 性能影响
存储介质写入延迟适用场景
内存盘0.1-1ms 0.1-1 毫秒高频交易行情数据
 SSD 固态硬盘2-5ms电商大促页面缓存
机械硬盘10-50ms低频访问日志归档
1.4 风险预警
  • 内存盘容量溢出:若临时文件总量超过内存盘大小,引发OOM(需监控/memdisk使用率)

  • 原子移动失败:网络抖动导致临时文件未完整迁移,触发proxy_next_upstream重试机制


2) proxy_cache_path:缓存系统的「核心仓库」
proxy_cache_path /memdisk/proxy 
    levels=1:2 
    keys_zone=cache_proxy:1024m 
    inactive=15m 
    max_size=8168m;
参数逐层拆解
2.1)  存储拓扑:levels=1:2
  • 目录结构

    /memdisk/proxy
    ├── a/    ← 1级目录(1字符命名,16进制)
    │   ├── 1b/  ← 2级目录(2字符命名)
    │   │   └── 缓存文件(MD5哈希值命名)
    │   └── c3/
    └── d/
  • 设计价值

    • 避免单目录文件数超过ext4的5000万inode限制

    • 提升SSD随机读性能(目录分散降低锁竞争)

2.2) 内存元数据区:keys_zone=cache_proxy:1024m
  • 内存消耗公式

    每条缓存元数据 ≈ 200字节  
    最大缓存键数量 = 1024MB / 200B ≈ 5,368,709 条  
2.3) 生命周期管理
  • inactive=15m

    • 含义:15分钟内未被访问的缓存视为冷数据,触发LRU淘汰

    • 误删防御:结合proxy_cache_background_update on实现热更新保活

  • max_size=8168m

    • 动态权重:实际占用空间 = 文件大小 + 文件系统块开销(通常+10%)

    • 溢出处理:触发cache manager进程按LRU清理,写入error_log警告

2.4) 极端场景测试
测试用例预期行为日志关键字
写入8.5G缓存触发LRU清理cache manager process exited abnormally
内存盘写满返回502错误no space left on device
共享内存溢出新缓存被拒could not add new key

相关文章:

  • 【场景应用5】深入探讨去噪扩散概率模型及训练推理过程
  • 电路方案分析(二十)TPS63xxx系列DC/DC电源EMI PCB设计方案
  • Odoo 部署本地 把現時的excel計算表格部署上odoo 教程
  • 利用 pyecharts 实现地图的数据可视化——第七次人口普查数据的2d、3d展示(关键词:2d 、3d 、map、 geo、涟漪点)
  • 基于Yolov8的植物病虫害检测系统
  • Linux线程属性与多线程开发:API详解与实战代码解析
  • 【一起来学kubernetes】37、lstio使用详解
  • 【前端】webpack一本通
  • HTML入门—表格与表单设计
  • 十大PDF解析工具在不同文档类别中的比较研究
  • HTTP 协议-应用层
  • STM32蓝牙连接Android实现云端数据通信(电机控制-开源)
  • Unity UI中的Pixels Per Unit
  • 从源码安装ROS的serial包(替换github的方案)
  • Python中的strip()
  • VSCode CMake调试CPP程序
  • 闲鱼分销玩法详解
  • 深入解读 React 纯组件(PureComponent)
  • 【Chain(链) 和 LCEL(LangChain Expression Language) 】概念区,用途差异对比
  • JavaScript学习教程,从入门到精通, JavaScript 函数全面解析与案例实践(11)
  • php网站管理系统下载/app营销策略有哪些
  • 上海三大设计院/宁波最好的seo外包
  • 网站建设公司的年报/企业培训体系搭建
  • 网站建设公司-山而/长尾词在线挖掘
  • 做二手房产网站多少钱/如何做推广最有效果
  • 是网站建设专业好/关注公众号一单一结兼职