MATRIX Delayed gratification

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 太“传统”。🥲

快来做第一个评论的人吧~
^