LLMProxy替换Nginx私有大模型网关

lxiol

原文链接:https://mp.weixin.qq.com/s/3dfco8ZP1aTdGTIzolJOGg

读完这篇你能带走什么:用 3 个配置块搭起一个 LLM 专用网关,解决 Nginx 的流式延迟、鉴权缺失、To

读完这篇你能带走什么
:用 3 个配置块搭起一个 LLM 专用网关,解决 Nginx 的流式延迟、鉴权缺失、Token 盲区三个问题。
适用:已在用 Nginx 代理 vLLM/Ollama/TGI 的私有部署场景 | 不适用:需要 WAF、复杂路由规则的场景

你有没有遇到过这种情况:

vLLM 服务本身响应很快,但经过 Nginx 之后,第一个 token 要等好几秒才出来。查了半天,发现是 proxy_buffering 没关;关了之后,又发现 proxy_read_timeout 设短了,流式连接中途断了。

更麻烦的是,Nginx 对 LLM 完全是透明的——它不知道你在做 SSE 流式推理,也不知道这次请求用了多少 token,更不知道谁在调用你的接口。

Nginx 不是做错了什么。它只是个通用代理,不懂 LLM 的语言。

2026 年 1 月,有人用 Go 写了一个专门替换这个位置的工具:LLMProxy。单二进制,YAML 配置,镜像 < 20MB。下面直接上配置。

问题拆解:Nginx 在 LLM 场景下的三个具体问题

问题 1:SSE 流式请求首 token 延迟

原因很简单:Nginx 默认会缓冲响应,攒够一批字节才转发。流式推理每次只吐几个 token,永远攒不满,要等超时或者缓冲区填满才发出去。

1
nginx# Nginx 的正确配置,但容易漏 proxy_buffering off; proxy_cache off; chunked_transfer_encoding on; proxy_read_timeout 300s; add_header Content-Type "text/event-stream";

漏了任何一行,SSE 就会出问题。而且这些配置对 LLM 以外的服务可能产生副作用。

问题 2:没有 API Key 鉴权

Nginx 做鉴权需要 Lua 脚本(OpenResty)或者外挂 auth_request 到另一个后端服务,对于只想保护一个 vLLM 接口的场景来说,这个代价太高了。

问题 3:Token 用量是黑盒

Nginx 只能记录 HTTP 状态码和字节数。谁用了多少 token?哪个 Key 快超配额了?这些信息要么需要解析响应体,要么直接看不到。

LLMProxy:专门为 LLM 场景设计的网关

LLMProxy 的核心设计选择非常克制:它不试图成为通用网关,只做好 LLM 流量这一件事。

能力

Nginx(通用)

LLMProxy(LLM 专用)

流式请求(SSE)

需手动配置多项参数

开箱即用

首 token 延迟

取决于配置

零缓冲透传

API Key 鉴权

需 Lua/外挂

内置,3 行配置

Token 用量统计

内置 Prometheus 指标

负载均衡

需 upstream

内置轮询/最少连接

配置复杂度

中高

极低

镜像体积

~150MB

< 20MB

30 分钟替换方案:完整配置

第一步:最小化启动

先用 5 行配置把服务跑起来:

1
yaml# config.yaml(最小配置) server:   listen: ":8080"  backends:   - name: vllm-main     url: "http://localhost:11434"  admin:   enabled: true   token: "change-this-token"   db_path: "./data/keys.db"
1
bashdocker run -d \   --name llmproxy \   --network host \   -v $(pwd)/config.yaml:\ /home/llmproxy/config.yaml \   ghcr.io/aiyuekuang/llmproxy:latest

验证是否正常代理流式请求:

1
bashcurl -s \   http://localhost:8080/v1/chat/completions \   -H "Content-Type: application/json" \   -d '{     "model": "qwen2.5:7b",     "stream": true,     "messages": [       {"role":"user","content":"hi"}     ]   }' # 预期:第一个 data: 在 1 秒内出现

第二步:加上 API Key 鉴权

在 config.yaml 追加 auth 配置块:

1
yamlauth:   enabled: true   header_names:     - Authorization     - X-API-Key   skip_paths:     - /health     - /metrics   pipeline:     - name: builtin_auth       type: builtin       enabled: true

重启服务后,创建第一个 API Key:

1
bashcurl -X POST \   http://localhost:8080/admin/keys/create \   -H "X-Admin-Token: change-this-token" \   -H "Content-Type: application/json" \   -d '{     "key": "sk-team-backend-001",     "user_id": "backend-team",     "quota": 1000000   }'

验证鉴权生效:

1
bash# 无 Key 应返回 401 curl -s -o /dev/null -w "%{http_code}" \   http://localhost:8080/v1/chat/completions \   -H "Content-Type: application/json" \   -d '{"model":"qwen2.5:7b","messages":[]}' # → 401  # 携带正确 Key 应返回 200 curl -s -o /dev/null -w "%{http_code}" \   http://localhost:8080/v1/chat/completions \   -H "Authorization: Bearer sk-team-backend-001" \   -H "Content-Type: application/json" \   -d '{"model":"qwen2.5:7b","messages":[     {"role":"user","content":"hi"}   ]}' # → 200

第三步:开启限流和 Token 统计

1
yamlrate_limit:   enabled: true   storage: memory   per_key:     enabled: true     requests_per_second: 10     max_concurrent: 5  usage:   enabled: true   reporters:     - name: local       type: builtin       enabled: true       builtin:         retention_days: 30  metrics:   enabled: true   path: /metrics

查看实时 Token 用量:

1
bashcurl -s http://localhost:8080/metrics \   | grep llmproxy_usage # llmproxy_usage_tokens_total{type="prompt"} 1540 # llmproxy_usage_tokens_total{ #   type="completion"} 3820

多后端负载均衡

如果你有多张显卡跑了多个推理实例:

1
yamlbackends:   - name: vllm-gpu0     url: "http://localhost:11434"     weight: 5   - name: vllm-gpu1     url: "http://localhost:11435"     weight: 5  routing:   enabled: true   load_balance: least_connections   retry:     enabled: true     max_retries: 2     initial_wait: 500ms

least_connections 模式会把新请求发给当前活跃连接最少的节点,对 LLM 长流式请求比 round-robin 更公平。节点故障时自动重试到其他后端。

什么情况下不换

LLMProxy 的克制是它的优点,也是它的边界:

  • 需要 WAF 防护
    :LLMProxy 没有 Web 应用防火墙,如果接口暴露在公网,仍然需要在前面放 Nginx 或 Cloudflare
  • 需要复杂路由规则
    :按 URL 路径分发、基于请求头的条件路由,这些 LLMProxy 目前不支持
  • 需要 TLS 终止
    :当前版本不内置 HTTPS,需要 Nginx 或 Caddy 在前面处理证书

典型的生产组合:Nginx(TLS + WAF)→ LLMProxy(鉴权 + 限流 + 统计)→ vLLM

行动清单

明天就能做的两件事:

① 替换 Nginx 的流式配置

1
bash# 测试当前 Nginx 流式延迟 time curl -s \   http://your-nginx-addr/v1/chat/completions \   -d '{"model":"...","stream":true,        "messages":[{"role":"user",        "content":"hi"}]}' \   | head -c 100 # 如果超过 2 秒看到第一个 data:,说明 Nginx 缓冲有问题

② 用最小配置跑起 LLMProxy 并对比延迟

1
bashdocker run -d --network host \   -v $(pwd)/config.yaml:\ /home/llmproxy/config.yaml \   ghcr.io/aiyuekuang/llmproxy:latest  # 同样测试,比较首 token 时间差距

好的工具通常很安静——它只做一件事,做得很好,让你忘了它的存在。LLMProxy 大概就是这样。

参考来源:LLMProxy GitHub(aiyuekuang/LLMProxy) | 私有化部署 LLM 时,别再用 Nginx 硬扛流式请求了(2026-05-22) | LLMProxy-Admin 知乎介绍(2026-01)

本文转载自微信公众号,如有侵权请联系删除。

  • 标题: LLMProxy替换Nginx私有大模型网关
  • 作者: lxiol
  • 创建于 : 2026-06-20 01:24:55
  • 更新于 : 2026-06-20 01:24:55
  • 链接: https://blog.lxiol.cn/2026/06/20/LLMProxy替换Nginx私有大模型网关/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。