vLLM推理服务如何做负载均衡?Nginx配置示例

在大模型应用如火如荼的今天,你有没有遇到过这样的场景👇:

“我们本地部署了Qwen大模型,用vLLM跑得飞快,但一到白天业务高峰期,API响应直接卡成PPT……”

别慌 😎,这其实是典型的单节点性能瓶颈 + 缺乏流量调度问题。好消息是——解法非常成熟:vLLM搭上Nginx,轻松实现高并发、可扩展的推理服务架构!


咱们今天不整虚的,直接上硬核实战:怎么用 Nginx 给 vLLM 做负载均衡?从原理到配置,再到生产级设计考量,一文讲透 ✅


先说结论:vLLM 负责“跑得快”,Nginx 负责“分得匀”。两者结合,才是真正的生产级部署方案。

为什么这么说?

因为哪怕 vLLM 再强,单个 GPU 实例总有上限 🧱。显存满了、请求堵了、延迟飙升了……这些都逃不过物理定律。而 Nginx 就像一个聪明的交通指挥官🚦,把源源不断的请求合理地分配给多个 vLLM “车道”,让整个系统吞吐翻倍还不怕挂掉。


那具体怎么干?我们一步步来拆解。

首先得明白,vLLM 到底凭什么能扛住高并发?

关键就在于它的两大黑科技:PagedAttention 和 连续批处理(Continuous Batching)。

传统 LLM 推理有个老大难问题:KV Cache 必须连续分配显存 → 容易碎片化 → 并发一多就 OOM。而 vLLM 的 PagedAttention 直接借鉴操作系统内存分页的思想,把 KV 缓存切成一个个“页”,按需加载和释放。这样一来,哪怕请求长短不一、完成时间不同,也能高效复用显存,利用率提升5~10倍不是吹 👏。

再加上连续批处理机制——新来的请求不用等前一批完全结束,只要还有空闲算力,立马插队进去一起算!GPU 几乎 never idle,吞吐自然起飞。

所以你看,vLLM 本身已经为高并发做好了准备。接下来的问题就是:如何横向扩容多个实例,并让它们协同工作?

答案就是反向代理层 —— Nginx 上场!

Nginx 不仅轻量、稳定、支持数万并发连接,还内置了强大的负载均衡能力。它就像一个前端门面,客户端只认它,背后有多少个 vLLM 实例完全透明。

来看一个典型的部署结构:

                    +------------------+
                    |   Client Apps    |
                    +--------+---------+
                             |
                     +-------v-------+
                     |     Nginx     | ← 入口统一,SSL终止,gzip压缩
                     +-------+-------+
                             |
           +-----------------+------------------+
           |                 |                  |
+----------v----------+ +----v-----+ +---------v----------+
| vLLM Node 1:8000    | |vLLM Node2| | vLLM Node 3:8000     |
| (A100, Qwen-72B)    | |(A10, smaller model)|             |
+---------------------+ +----------+ +--------------------+
           |                        |
           +-----------+------------+
                       |
               +-------v--------+
               | Shared Storage |
               | (NFS / S3)     |
               +----------------+

所有 vLLM 节点共享模型存储(比如 NFS 或对象存储),启动时各自加载权重。Nginx 作为唯一入口,负责将 /v1/chat/completions 这类请求转发出去。

那么问题来了:Nginx 怎么决定把请求发给哪个节点?

这就涉及负载算法的选择了。

默认轮询(Round Robin)当然可以,但如果各节点硬件配置不一样呢?比如一台是 A100,另一台是 A10……这时候就得上 加权轮询(Weighted Round Robin):

upstream vllm_backend {
    server 192.168.1.10:8000 weight=3;  # A100 强机,多分点活
    server 192.168.1.11:8000 weight=1;  # A10 小弟,少接点任务
}

更推荐的是 least_conn 策略——谁当前连接最少,就往谁那儿发。这对长文本生成特别友好,避免某个慢请求拖垮整个批次。

upstream vllm_backend {
    least_conn;

    server 192.168.1.10:8000 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8000 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8000 weight=1; # 老旧设备降权
}

注意这里的 max_fails 和 fail_timeout 是被动健康检查机制:连续失败3次后,该节点会被暂时剔除30秒,防止雪崩。

如果你追求更高可用性,还可以引入主动健康检查(需要 OpenResty 或第三方模块):

# 示例:使用 nginx_upstream_check_module
check interval=10 rise=2 fall=2 timeout=3 type=http uri=/health;

只要后端 vLLM 提供 /health 健康接口(返回200即可),Nginx 就能实时感知节点状态。

再来看看完整的 Nginx 配置模板,我已经帮你调好各种参数了 ⚙️:

worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 10240;
    use epoll;  # Linux 下性能最佳
}

http {
    upstream vllm_backend {
        least_conn;

        server 192.168.1.10:8000 weight=2 max_fails=3 fail_timeout=30s;
        server 192.168.1.11:8000 weight=2 max_fails=3 fail_timeout=30s;
        server 192.168.1.12:8000 weight=1 max_fails=3 fail_timeout=30s;

        # 可选:启用主动健康检查(需额外模块)
        # check interval=10 rise=2 fall=2 timeout=3 type=http uri=/health;
    }

    server {
        listen 80;
        server_name api.example.com;

        # 启用 gzip 压缩 JSON 响应,节省带宽
        gzip on;
        gzip_types application/json;

        location / {
            proxy_pass http://vllm_backend;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            # 长文本生成可能耗时较长,适当延长超时
            proxy_connect_timeout 60s;
            proxy_send_timeout 300s;
            proxy_read_timeout 300s;

            # 开启缓冲提升性能
            proxy_buffering on;
            proxy_buffer_size 128k;
            proxy_buffers 4 256k;
        }

        # HTTPS 支持(强烈建议生产环境开启)
        # listen 443 ssl;
        # ssl_certificate /etc/nginx/ssl/api.example.com.crt;
        # ssl_certificate_key /etc/nginx/ssl/api.example.com.key;
        # ssl_protocols TLSv1.2 TLSv1.3;
    }
}

💡 几个关键点提醒你注意:

  • proxy_set_header 一定要配全,尤其是 X-Forwarded-For,方便你在 vLLM 层做日志追踪或限流;
  • 超时时间设为300秒很常见,毕竟有些复杂 prompt 要生成几千字;
  • Gzip 压缩对 JSON 类响应效果显著,特别是返回大量文本时,体积能减少60%以上;
  • 如果你想灰度发布新版本模型?可以用 split_clients 按比例分流:
split_clients "${msec}" $backend {
    5%     vllm_staging;   # 5% 流量切到测试组
    *      vllm_backend;   # 其余走正式集群
}

location / {
    proxy_pass http://$backend;
    # ...
}

除了基本转发,你还应该考虑这些“生产级要素” 🔧:

✅ 安全加固

  • 在 Nginx 前加 WAF(如 ModSecurity)防 SQL 注入、恶意 payload;
  • 使用 JWT 或 API Key 认证,拒绝非法调用;
  • 日志脱敏处理,别把用户输入原样写进文件。

✅ 可观测性

  • vLLM 支持 Prometheus 指标暴露(--enable-prometheus 参数),监控 TPS、延迟、GPU 利用率;
  • Nginx 开启 access log,记录 request_time, status, $uri 等字段;
  • 用 Grafana 把指标串起来,一眼看出哪个节点变慢、哪类请求最耗资源。

✅ 滚动升级 & 灰度发布

  • 更新模型时,逐个停掉 vLLM 节点,加载新权重后再上线;
  • Nginx 自动检测健康状态,不会把请求打到正在重启的机器;
  • 结合命名空间或标签路由,实现多模型共存与动态切换。

✅ 成本优化技巧

  • 小模型部署在低配 GPU 上,通过 weight 控制流量分配;
  • 使用 GPTQ/AWQ 量化模型进一步降低显存占用;
  • 对非实时请求(如批量生成)走异步队列,错峰处理。

最后聊聊这个架构适合哪些场景?

🎯 企业私有化部署:不想把数据传到云端?自己搭一套安全可控的 AI 接口平台,支持内部系统调用。

🎯 AI SaaS 平台:对外提供统一 API,后台根据租户自动路由到对应模型实例,资源隔离又高效。

🎯 高并发内容生成:营销文案、商品描述、客服话术批量产出,QPS 动辄上千,必须靠集群扛住。

🎯 科研机构共享平台:多个课题组共用 GPU 池,vLLM + Nginx 实现资源池化与公平调度。


总结一下 💬:

单靠 vLLM,你能做出“快”的推理服务;
但加上 Nginx 负载均衡,才能做出“稳、弹、可观测”的生产系统。

这套组合拳的核心价值在于:

✨ 横向可扩展:不够用了?加机器就行,Nginx 自动纳管;
✨ 故障自愈:某节点宕机不影响整体服务;
✨ 无缝升级:支持灰度、回滚、A/B测试;
✨ 生态兼容:OpenAI 接口标准,现有应用零改造接入。

🚀 所以说,当你看到“vLLM 单机压测 800 QPS”的时候,别激动得太早——真正厉害的是把它变成“3200 QPS 且永不宕机”的工程能力。

而这,正是 Nginx 存在的意义。

现在,是不是觉得手里的大模型更有“生产力”味道了?😉

更多推荐