Nginx 反代 2API 后缓存命中率暴跌?原来是 underscores_in_headers 在“偷吃”请求头
最近给 GPT Plus 账号做 API 中转时,我突然发现一个诡异现象:
- 同样的模型
- 同样的 prompt
- 同样的账号池
- 请求量甚至更低了
结果缓存命中率却像坐了滑梯一样往下掉。📉
一开始我还以为:
- OpenAI 改了缓存策略
- session 机制更新了
- 2API 有 bug
- Cloudflare 在抽风
最后排查了半天,真正的凶手居然是:
underscores_in_headers on;没开。😅
问题现象
我的架构大概是:
Client
↓
Nginx Reverse Proxy
↓
2API
↓
OpenAI结果发现:
- cache hit rate 明显降低
- 对话上下文像“失忆”一样
- 某些 session 无法复用
- token 消耗明显变高
- 同一个 prompt 频繁重新计算
但日志里看请求又是正常的。
这时候事情就开始变得像“幽灵 bug”了。
真正原因
很多 2API/OpenAI 中转方案会使用类似:
session_id: xxxxx这样的 Header 来维持:
- 会话一致性
- 上游缓存
- session stickiness
- prompt cache
但 Nginx 默认有一个非常坑的行为:
它会忽略带下划线 _ 的 Header。也就是说:
session_id这种 Header 会被 Nginx 直接丢掉。
于是:
客户端:
session_id: abc123到了后端:
(没了)2API 后端根本收不到 session_id。
于是缓存系统看见的请求全都像:
“新的陌生用户来了。”
缓存命中率自然直接爆炸。
为什么 Nginx 会这样设计?
这是个历史遗留问题。
早期 CGI/FastCGI 环境里:
Header-Name会被转换成:
HTTP_HEADER_NAME而:
Header_Name也会变成:
HTTP_HEADER_NAME会产生歧义。
于是 Nginx 干脆:
默认禁用带 _ 的 Header。这个设定在现代 API 世界里简直像一个埋在地板下的乐高积木。🧱
平时感觉不到。
一脚踩上去直接升天。
解决方法
在 Nginx 配置里加入:
underscores_in_headers on;例如:
http {
underscores_in_headers on;
server {
listen 443 ssl;
location / {
proxy_pass http://backend;
}
}
}然后重载 Nginx:
nginx -s reload或者:
systemctl reload nginx如何验证 Header 是否被吞?
可以在后端打印请求头:
Python Flask 示例:
from flask import request
print(request.headers)或者 Node.js:
console.log(req.headers)如果开启前:
{
"authorization": "Bearer xxx"
}开启后:
{
"authorization": "Bearer xxx",
"session_id": "abc123"
}那就说明破案成功了。🕵️
我这里的实际效果
修复后:
- cache hit rate 明显恢复
- token 消耗下降
- 响应速度变快
- session 终于稳定
- 上游不再疯狂重复推理
属于是:
一行配置,救活整个缓存系统。
顺便提醒几个类似坑
除了 session_id,这些 Header 也可能受影响:
user_id
chat_id
device_id
x_session_key
cf_connecting_ip如果你的业务依赖自定义 Header:
建议直接:
underscores_in_headers on;否则调试时会非常折磨。
总结
如果你:
- 在用 Nginx 反代 2API/OpenAI
- 发现缓存命中率异常低
- session 不稳定
- token 消耗离谱
- 明明开了缓存却像没开
先检查这一行:
underscores_in_headers on;很多时候问题不是 AI 太聪明。
而是 Nginx 太“传统”。🥲