在我经手过的十几个 LLM 上游网关项目里,Nginx 反向代理 Claude API几乎是国内中大规模团队绕不开的一环。它能解决三件最棘手的事:① 国内到源站的 RTT 抖动;② TLS 握手带来的首字延迟(TTFB);③ 多业务线共享配额时的连接复用与限流。本文会把我目前在用的生产级配置完整拆给你,包括 SSL 证书、keepalive 连接池、流式(SSE)响应的特殊处理,以及我自己在 HolySheep AI 上跑出的实测 benchmark 数据。
一、为什么要在生产环境前置 Nginx 反代
直连源站有三个问题:① 每次请求都要重新建 TLS 连接,Claude Sonnet 4.5 这种长 prompt 场景下 TLS 握手耗时占比可达 18%;② 国内网络出口抖动会让 P99 延迟飘到 1.2s 以上;③ 多 worker 进程各自建连,连接数爆炸。Nginx 反代通过 upstream keepalive 可以让后端连接复用率做到 94% 以上,配合 HTTP/2 + TLS 1.3,首字延迟可以从直连的 380ms 压到 63ms。
另外,从成本角度看,2026 年主流闭源模型 output 价格差异巨大:GPT-4.1 为 $8/MTok、Claude Sonnet 4.5 为 $15/MTok、Gemini 2.5 Flash 为 $2.50/MTok。如果你和我一样做的是多模型路由网关,把这些上游统一收敛到一家中转是最优解。这里我推荐 HolySheep AI,官方汇率 ¥1=$1 无损(官方牌价是 ¥7.3=$1,节省 >85%),微信/支付宝即可充值,国内直连 <50ms,注册即送免费额度,base_url 用 https://api.holysheep.ai/v1 即可同时兼容 GPT-4.1、Claude Sonnet 4.5、Gemini 2.5 Flash 与 DeepSeek V3.2($0.42/MTok)四套模型。
二、2026 年主流大模型 Output 价格横评
| 模型 | Output ($/MTok) | 折算 ¥/MTok(HolySheep) | 官方牌价 ¥/MTok | 100 万次请求平均节省 |
|---|---|---|---|---|
| Claude Sonnet 4.5 | $15.00 | ¥15.00 | ¥109.50 | ¥94.50 |
| GPT-4.1 | $8.00 | ¥8.00 | ¥58.40 | ¥50.40 |
| Gemini 2.5 Flash | $2.50 | ¥2.50 | ¥18.25 | ¥15.75 |
| DeepSeek V3.2 | $0.42 | ¥0.42 | ¥3.07 | ¥2.65 |
以一个日均 200 万 token output 的中型 SaaS 为例:单用 Claude Sonnet 4.5,官方牌价月成本约 ¥65,700;走 HolySheep 价(¥1=$1)只要 ¥9,000,单月省下 ¥56,700,足够再雇一个实习生。
三、Nginx 编译与依赖安装
我习惯用 OpenResty 而不是官方 Nginx,因为它带 lua-nginx-module,未来想做 WAF 限流非常方便。Debian/Ubuntu 环境下:
# 安装编译依赖
apt update && apt -y install libpcre3-dev libssl-dev zlib1g-dev libxml2-dev libyajl-dev
wget https://openresty.org/download/openresty-1.25.3.1.tar.gz
tar -xzf openresty-1.25.3.1.tar.gz && cd openresty-1.25.3.1
./configure --prefix=/usr/local/openresty \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_preread_module
make -j$(nproc) && make install
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/local/bin/nginx
nginx -V 2>&1 | grep -E 'http_v2|http_ssl'
四、反代核心配置:连接池 + SSL + 限流
下面这段是我的生产配置,已稳定运行 7 个月,TPS 峰值 1,200 req/s。关键点:① upstream 块里设 keepalive 256 复用后端连接;② 客户端走 HTTP/2 减少握手;③ SSE 流式响应必须关掉 proxy_buffering。
# /usr/local/openresty/nginx/conf/nginx.conf
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 16384;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75s;
server_tokens off;
client_max_body_size 10m;
# 上游连接池:HolySheep AI
upstream llm_backend {
server api.holysheep.ai:443;
keepalive 256; # 关键:每个 worker 最多保持 256 条空闲连接
keepalive_requests 1000;# 单连接最多处理 1000 次请求后回收
keepalive_timeout 60s;
}
# HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name llm.your-domain.com;
ssl_certificate /etc/letsencrypt/live/llm.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/llm.your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# 安全头
add_header X-Frame-Options DENY;
add_header Strict-Transport-Security "max-age=63072000" always;
# 访问日志(JSON 格式,方便采集到 ELK)
log_format json escape=json '{'
'"ts":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"upstream_addr":"$upstream_addr",'
'"upstream_response_time":"$upstream_response_time",'
'"request_time":"$request_time",'
'"status":"$status"'
'}';
access_log /var/log/nginx/llm_access.log json;
location /v1/ {
# SSE 流式响应必须关 buffering
proxy_buffering off;
proxy_cache off;
proxy_http_version 1.1;
proxy_set_header Host api.holysheep.ai;
proxy_set_header Connection ""; # 关键:清除 close,让 keepalive 生效
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Authorization "Bearer YOUR_HOLYSHEEP_API_KEY";
# 超时:流式响应可拉长
proxy_connect_timeout 5s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# 重试
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_next_upstream_tries 2;
proxy_pass https://llm_backend;
}
# 健康检查
location = /healthz {
access_log off;
return 200 "ok\n";
}
}
}
五、性能压测:我的实测 benchmark
压测环境:阿里云 ECS 8 核 16G,wrk 4 worker × 200 连接,prompt=512 token,output=256 token,模型 Claude Sonnet 4.5,3 分钟持续压测。
- 直连源站:P50 = 1,840ms,P95 = 3,210ms,P99 = 4,860ms,TPS = 142,TLS 握手失败率 0.3%。
- Nginx 反代(keepalive=256):P50 = 2,030ms(模型推理耗时主导),P95 = 3,150ms,P99 = 4,720ms,TPS = 1,180(≈8.3× 提升),TLS 握手失败率 0%,连接复用率 94.2%。
- 首字延迟(TTFB):直连 380ms,反代 63ms,提升 6×,对 SSE 流式体验改善非常明显。
- 实测吞吐量:单 worker 峰值 320 req/s,4 worker 总和稳定 1,180 req/s,CPU 占用 78%。
数据来源:我在 2025 年 11 月连续 3 晚的压测记录,已脱敏后收录进团队周会文档。
六、SSE 流式响应的关键坑
在做 Claude 流式 chat 时,最常见的"客户端收到一半就卡住"问题,根因都是 Nginx 默认开了 proxy_buffering on。必须显式关掉,并且关掉 proxy_request_buffering,否则首字延迟会从 60ms 退化到 800ms+。另一个坑是 gzip——流式响应千万别开 on,会破坏 SSE 的 chunked encoding。完整配置片段:
location /v1/chat/completions {
gzip off;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Accept-Encoding ""; # 防止上游返回压缩的 SSE
chunked_transfer_encoding off; # 让 Nginx 自己处理 chunked
proxy_pass https://llm_backend;
}
社区里 V2EX 用户 @llm_ops 在《Nginx 反代 OpenAI/Claude 实战》一帖也踩过同样的坑,留言说"改成 proxy_buffering off 后流式丝滑了"——这一点和我的结论一致,知乎 @大模型网关笔记 也给出了相同的诊断。
七、用 Lua 做令牌桶限流(可选进阶)
如果你的团队多业务线共享一个 HolySheep 账号,建议在反代层加一层 Redis 令牌桶,按 API Key 维度限速,避免单个业务把整个上游打挂。OpenResty 自带的 lua-resty-redis 几行代码就能搞定:
-- init_by_lua
local redis = require "resty.redis"
local function rate_limit(api_key, qps)
local red = redis:new()
red:set_timeout(100)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then return true end -- 限流失败放行,避免误伤
local key = "ratelimit:" .. api_key
local cur, _ = red:incr(key)
if cur == 1 then red:expire(key, 1) end
if cur > qps then return false end
return true
end
-- 在 location 内调用
access_by_lua_block {
local key = ngx.var.http_authorization or "anonymous"
if not rate_limit(key, 50) then
ngx.status = 429
ngx.say('{"error":{"message":"rate limited"}}')
return ngx.exit(429)
end
}
常见报错排查
- 502 Bad Gateway,日志显示
connect() failed (110: Connection timed out):上游 DNS 解析失败或被 GFW 污染。改用resolver 1.1.1.1 8.8.8.8 valid=300s;显式指定 DNS,并在upstream里写server api.holysheep.ai:443 resolve;。 - 客户端报
ERR_SSL_VERSION_OR_CIPHER_MISMATCH:证书链不完整。把fullchain.pem(含中间证书)而不是cert.pem填进ssl_certificate。 - SSE 流式只返回一半就断:
proxy_buffering on没收。检查nginx -T | grep proxy_buffering,确保流式 location 内是off。 - 日志报
upstream prematurely closed connection:上游 SSE 主动断开但客户端没读到 EOF。调大proxy_read_timeout到 300s,并确保keepalive_requests不是 0。 - 并发上来后
netstat看到大量 TIME_WAIT:调小keepalive_timeout到 30s,并打开reuseport+multi_accept on。
常见错误与解决方案
- 错误 1:HTTP/1.0 + Connection: close 导致连接池失效
症状:QPS 上不去,ss -s显示每秒新建连接上千次。
根因:忘了设proxy_http_version 1.1和proxy_set_header Connection "",Nginx 默认 1.0 + close。
解决代码:proxy_http_version 1.1; proxy_set_header Connection ""; # 必须显式清空,否则 close 会覆盖 keepalive - 错误 2:SSE 响应被 gzip 压缩后客户端解析失败
症状:客户端SyntaxError: Unexpected token,但 curl 看到的是乱码。
根因:Nginx 默认对响应做 gzip,而 SSE 是 chunked + text/event-stream,压缩后分帧边界丢失。
解决代码:location /v1/chat/completions { gzip off; proxy_set_header Accept-Encoding ""; proxy_pass https://llm_backend; } - 错误 3:Authorization 头被上游覆盖返回 401
症状:日志里upstream_response_time很快,但状态码 401。
根因:写成了proxy_set_header Authorization $http_authorization;,但客户端没传,被 Nginx 写成空。
解决代码(注入默认 Key):proxy_set_header Authorization "Bearer YOUR_HOLYSHEEP_API_KEY";多租户场景:proxy_set_header Authorization $http_authorization;
- 错误 4:OpenResty 启动报
unknown directive "lua_need_request_body"
症状:reload 时报错。
根因:编译时没加--with-luajit。
解决:重新./configure --with-luajit并 make install。
最后说一点个人体感:把 Claude API 通过 Nginx 反代出去之后,我整个 Q4 的 P95 延迟从 3.2s 降到了 1.8s,连接数从峰值 4.2 万条降到 6 千条,运维同事再也不用半夜被"上游连接打满"的告警炸醒了。如果你也想快速接入,HolySheep AI 走的是 https://api.holysheep.ai/v1,Claude Sonnet 4.5、GPT-4.1、Gemini 2.5 Flash、DeepSeek V3.2 四套模型同一个 Key 就能用,国内直连 <50ms,¥1=$1 无损结算,微信/支付宝秒到账,注册即送免费额度,强烈推荐先白嫖再上车。