8卡服务器(4服务x 2卡)Nginx 负载均衡配置,与百分位延迟说明

A.1 Nginx 负载均衡详细配置

A.1.1 当前生产配置

upstream vllm_backend {
least_conn;
server 10.255.254.44:8000;
server 10.255.254.44:8001;
server 10.255.254.44:8002;
server 10.255.254.44:8003;
}

server {
listen 0.0.0.0:2196;
server_name _;

location /v1/ {
proxy_pass http://vllm_backend;
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 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
proxy_buffering off;
proxy_socket_keepalive on;
}

location / {
return 444;
}
}

A.1.2 配置逐行说明

|---------------------------------|------------------|-------------------------------------------|
| 配置项 | 值 | 作用 |
| least_conn | --- | 最少连接调度:将请求发给当前活跃连接数最少的后端实例,确保负载均匀 |
| server 10.255.254.44:8000~8003 | 4 个后端 | 4 个 vLLM TP=2 实例,每个实例占用 2 张 4090 |
| listen 0.0.0.0:2196 | 公网 2196 端口 | 对外暴露统一 API 入口 |
| proxy_set_header 系列 | 透传客户端信息 | 让后端 vLLM 看到真实客户端 IP |
| proxy_*_timeout 600s | 600 秒 | 匹配 vLLM 长生成时间,避免 Nginx 提前断开 |
| proxy_buffering off | 关闭缓冲 | 流式响应实时返回,不等待完整响应 |
| proxy_socket_keepalive on | 开启 TCP Keepalive | 维持长连接,减少 TCP 握手开销 |
| location / { return 444; } | 静默拒绝 | 拦截非法扫描请求(如漏洞探测),不返回任何内容 |

A.1.3 负载均衡策略对比

|---------------------|-------------|---------------------|-----------------------|
| 策略 | 配置 | 适用场景 | 本测试表现 |
| ip_hash | ip_hash; | 会话保持(同一 IP 固定到同一后端) | ❌ 单实例过载,其余空闲 |
| round_robin | 默认 | 简单轮询 | ⚠️ 请求长度不均时可能负载不均 |
| least_conn | least_conn; | 长连接/异构请求 | ✅ 最优,4 实例均匀负载 |
| least_time | 需第三方模块 | 响应时间敏感 | --- 未测试 |

本测试选择 least_conn 的原因: - vLLM 请求处理时间长(10-30s),属于长连接场景 - 不同请求生成 token 数不同(200-300),处理时间异构 - least_conn 能动态将新请求发给当前最空闲的实例

A.1.4 后端实例架构

客户端请求

Nginx (2196端口, least_conn)

├─→ vLLM-8000 (GPU 0+1, TP=2)
├─→ vLLM-8001 (GPU 2+3, TP=2)
├─→ vLLM-8002 (GPU 4+5, TP=2)
└─→ vLLM-8003 (GPU 6+7, TP=2)

  • 每个实例独立进程,互不影响
  • 实例故障时 Nginx 自动剔除(需配合健康检查)
  • 单实例重启不影响其他实例服务

A.1.5 健康检查建议(生产增强)

当前配置无主动健康检查,建议增加:

upstream vllm_backend {
least_conn;
server 10.255.254.44:8000 max_fails=3 fail_timeout=30s;
server 10.255.254.44:8001 max_fails=3 fail_timeout=30s;
server 10.255.254.44:8002 max_fails=3 fail_timeout=30s;
server 10.255.254.44:8003 max_fails=3 fail_timeout=30s;
}

或使用 nginx_upstream_check_module 做主动健康检查:

upstream vllm_backend {
least_conn;
server 10.255.254.44:8000;
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "GET /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}


A.2 百分位延迟(P50 / P90 / P99)说明

A.2.1 什么是百分位延迟?

百分位延迟是衡量请求延迟分布的统计指标,比"平均延迟"更能反映真实用户体验。

|-------------|-----------------|-------------------------------|
| 指标 | 定义 | 通俗理解 |
| P50 | 50th Percentile | 中位数:50% 请求比它快,50% 比它慢 |
| P90 | 90th Percentile | 90% 请求 ≤ 这个值,10% 更慢 |
| P99 | 99th Percentile | 99% 请求 ≤ 这个值,仅 1% 更慢 |

A.2.2 为什么不能用"平均延迟"?

平均延迟有欺骗性

10 个请求的延迟:1s, 1s, 1s, 1s, 1s, 1s, 1s, 1s, 1s, 100s

平均延迟 = 10.9s ← 看起来"还行"
P99 延迟 = 100s ← 有一个用户等了 100 秒!

平均延迟掩盖了尾部用户的痛苦。

A.2.3 百分位延迟的计算方法

将 N 个请求的延迟从小到大排序:

排序后: 18s, 19s, 19s, 20s, 20s, 21s, 21s, 22s, 23s, 100s
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
P10 P20 P30 P40 P50 P60 P70 P80 P90 P100

  • P50 = 第 5 个值 = 20s(中位数)
  • P90 = 第 9 个值 = 23s(90% 用户 ≤ 23s)
  • P99 = 第 9.9 个值 ≈ 100s(99% 用户 ≤ 100s)

A.2.4 本测试中的百分位延迟数据

4090 测试结果(健康系统)

|-----|-----|-------|-------|-------|-------------|--------|
| 并发 | 请求数 | P50 | P90 | P99 | P99-P50 | 状态 |
| 1 | 50 | 19.2s | 19.2s | 19.2s | 0ms | ✅ 完全均匀 |
| 10 | 50 | 20.5s | 20.5s | 20.5s | 0ms | ✅ 完全均匀 |
| 20 | 50 | 19.8s | 19.8s | 19.8s | 0ms | ✅ 完全均匀 |
| 50 | 50 | 20.7s | 20.7s | 20.7s | 0ms | ✅ 完全均匀 |
| 100 | 50 | 20.4s | 20.4s | 20.4s | 0ms | ✅ 完全均匀 |
| 100 | 100 | 20.9s | 20.9s | 20.9s | 0ms | ✅ 完全均匀 |
| 200 | 150 | --- | --- | 21.5s | --- | ✅ 尾部稳定 |
| 250 | 250 | --- | --- | 22.2s | --- | ✅ 尾部稳定 |

特征:P50 = P90 = P99

B60 参考结果(压力系统)

|-----|------|------|------|-------------|---------|
| 并发 | P50 | P90 | P99 | P99-P50 | 状态 |
| 150 | 110s | 112s | 112s | 2s | ⚠️ 轻微尾部 |
| 200 | 151s | 164s | 184s | 33s | ❌ 尾部恶化 |

特征:P99 >> P90 >> P50

A.2.5 百分位差距的含义

|----------------|-----------------|-------------------|
| P99-P50 差距 | 系统状态 | 说明 |
| < 1s | ✅ 健康 | 调度公平,资源充足,所有请求一致 |
| 1-5s | ⚠️ 轻度压力 | 10% 请求开始变慢,调度轻微不均 |
| 5-20s | ❌ 中度瓶颈 | 尾部请求明显饥饿,队列堆积 |
| > 20s | ❌ 严重瓶颈 | 系统过载,部分请求长时间等待 |

A.2.6 本测试结论

4090 + vLLM 表现 : - 并发 250 以内,P99-P50 ≈ 0-3s - 说明 vLLM continuous batching 调度器工作完美 - 无请求被"饿死",所有用户获得一致体验 - GPU 算力是瓶颈,但调度器不是瓶颈

对比 B60 : - B60 并发 200 时 P99-P50 = 33s (尾部恶化 22%) - 4090 并发 250 时 P99-P50 ≈ 3s(零恶化)

4090 的调度公平性远超 B60。

A.2.7 生产环境的 P99 承诺

|--------|-----------------|---------------|
| 业务类型 | 建议 P99 目标 | 理由 |
| 实时客服 | < 5s | 用户不能等,超时即流失 |
| 在线 API | < 30s | 多数应用可接受,需进度提示 |
| 批处理/后台 | < 120s | 容忍度高,但需监控 |
| SLA 合同 | 必须写 P99 | 平均延迟无法作为法律承诺 |

A.2.8 如何解读本测试报告中的延迟数据

并发=200, 请求=150:
平均延迟: 22.3s
P50: --- | P90: --- | P99: 21.5s

解读:

  • 平均延迟 22.3s 与 P99 21.5s 接近 → 分布均匀,无异常值
  • 如果平均 >> P99,说明有少量请求极慢(被平均拉高了)
  • 本测试中平均 ≈ P99 → 所有请求处理时间一致 ✅

A.3 配置与监控命令速查

查看 Nginx 配置

cat /etc/nginx/conf.d/vllm_lb.conf

重载 Nginx

sudo nginx -t && sudo systemctl reload nginx

查看后端连接分布

sudo ss -tnp | grep -E "8000|8001|8002|8003" | grep ESTAB | awk '{print $4}' | sort | uniq -c

查看 vLLM 实例日志

sudo journalctl -u vllm-8000 -f --no-pager | grep -E "chat.completions|Engine.*throughput"

查看 GPU 利用率

nvidia-smi --query-gpu=index,utilization.gpu,memory.used,temperature.gpu --format=csv

相关推荐
.千余14 小时前
【测试】测试用例设计攻略(6大设计方法)
服务器·网络·笔记·学习·测试用例
呆萌的代Ma14 小时前
Linux服务使用Nginx配置域名并使用certbot提供SSL
linux·nginx·ssl
热爱Liunx的丘丘人14 小时前
搭建一个 Web + 数据库系统(Nginx+PHP+MySQL)
数据库·nginx·php
tang74516396214 小时前
华为云服务器Ubuntu 24.04 安装 Kafka20260318
服务器·ubuntu·华为云
wanhengidc14 小时前
服务器如何防范病毒攻击
运维·服务器·游戏
ylatin14 小时前
frp使用 网络
运维·服务器·网络
z2023050814 小时前
RDMA之NVIDIA Zero Touch RoCE (ZTR),和RTT的应用(9)
linux·服务器·网络·人工智能·ai
晚风予卿云月15 小时前
【Linux】初步构建框架—虚拟地址空间(三)—进程与内存管理的解耦优势、深入理解vm_area_struct
linux·运维·服务器·面试
土星云SaturnCloud15 小时前
边缘计算微服务器自然散热技术详解
服务器·人工智能·ai·边缘计算