跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

实战演示 Nginx 利用 map 块根据请求 Content-Type 动态调整 proxy_cache 策略

map 指令用于预计算式变量映射,通过 $http_content_type 控制缓存开关与 TTL:JSON 不缓存,HTML 缓存 5 分钟,其余默认 1 小时;需注意请求头来源、正则引号、bypass/no_cache 区别及空 Content-Type 显式处理。 理解 map 块在缓存策略中的作用 map 是 Nginx 的核心模块
ngx_http_map_module
提供的指令,用于根据某个变量(如请求头、URI、参数等)的值,映射出一个新的变量。它不是条件判断,而是**预计算式变量赋值**——在请求处理早期就完成匹配,性能高效且可被缓存机制直接引用。 用它控制
proxy_cache
行为的关键在于:将
$http_content_type
(客户端发来的请求体 MIME 类型)映射为一个缓存开关或缓存区域名,再通过
proxy_cache
、
proxy_cache_bypass
等指令联动生效。 配置示例:按 Content-Type 区分缓存启用与过期时间 以下是一个生产可用的配置片段,实现: •
application/json
请求不缓存 •
text/html
缓存 5 分钟 • 其他类型(如
application/javascript
、
text/css
)缓存 1 小时
http { # 定义缓存区域 proxy_cache_path /var/cache/nginx/api_cache levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m use_temp_path=off;
# 根据 Content-Type 映射缓存开关(on/off)
map $http_content_type $cache_enabled {
    default         "on";
    ""              "off";           # 无 Content-Type 头时禁用
    "~*application/json" "off";
    "~*text/html"   "on";
}

# 映射缓存有效时间(单位秒)
map $http_content_type $cache_ttl {
    default         "3600";          # 默认 1h
    "~*text/html"   "300";           # HTML 5min
    "~*application/json" "0";       # JSON 不缓存(设为 0 即忽略 Expires/Cache-Control)
}

server {
    listen 80;
    location /api/ {
        proxy_pass http://backend;

        # 启用缓存并引用映射变量
        proxy_cache api_cache;
        proxy_cache_valid 200 302 $cache_ttl;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;

        # 仅当 $cache_enabled == "on" 时才真正缓存
        proxy_cache_bypass $cache_enabled;
        proxy_no_cache $cache_enabled;

        # 可选:透传原始 Content-Type 到响应头,便于调试
        add_header X-Cache-Status $upstream_cache_status;
        add_header X-Cache-Enabled $cache_enabled;
        add_header X-Cache-TTL $cache_ttl;
    }
}
} Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载 关键细节说明与避坑提示 该配置看似简洁,但有几个易错点必须注意: Content-Type 来源是请求头,不是响应头 :
$http_content_type
读取的是客户端发起请求时携带的
Content-Type
(如 POST/PUT 请求体格式),而非后端返回的响应类型。若想按响应类型缓存,应改用
$upstream_http_content_type
,并配合
proxy_cache_valid
的 MIME 类型匹配语法(如
proxy_cache_valid 200 302 10m text/html;
) 正则匹配需加引号和修饰符 :map 中使用
~*
表示大小写不敏感正则;整个 pattern 必须用双引号包裹,否则含斜杠(如
application/json
)会解析失败 proxy_cache_bypass 和 proxy_no_cache 逻辑不同 :
proxy_cache_bypass $cache_enabled
:当变量值为非空、非"0"、非"off"、非"false"时,跳过缓存直接转发
proxy_no_cache $cache_enabled
:当变量值为真时,即使命中缓存也不返回,而是重新请求上游并覆盖旧缓存 实际中常二者配合使用,确保“不缓存”的请求既不读也不写缓存 空 Content-Type 或缺失头需显式处理 :很多工具(如 curl 不带 -H)或浏览器表单提交可能不带
Content-Type
,此时
$http_content_type
为空字符串,必须在 map 中用
""
明确匹配,否则走 default 分支导致误缓存 验证与调试方法 上线前务必用真实请求验证行为是否符合预期: 发送不同 Content-Type 的请求,观察响应头:
curl -H "Content-Type: application/json" -I http://your-domain/api/user
curl -H "Content-Type: text/html" -I http://your-domain/api/page
检查
X-Cache-Status
是否为
MISSED
/
HIT
/
BYPASS
,以及
X-Cache-Enabled
值是否正确 查看缓存目录文件变化:
find /var/cache/nginx/api_cache -type f | head -5
结合
nginx -t && nginx -s reload
后观察新请求是否生成缓存文件 开启 Nginx debug 日志(临时): 在 events 块中加
debug_connection 127.0.0.1;
,并在 error_log 中设
error_log /var/log/nginx/debug.log debug;
,可追踪 map 匹配过程和缓存决策路径

相关文章