All checks were successful
Build and Deploy Backend / build-and-deploy (push) Successful in 5m41s
122 lines
3.9 KiB
Markdown
122 lines
3.9 KiB
Markdown
# hw_service_go 并发压力测试报告
|
||
|
||
> 测试时间:2026-03-03
|
||
> 测试目标:`wss://qiyuan-rtc-api.airlabs.art/xiaozhi/v1/`
|
||
> Pod 配置:单 Pod,CPU 100m~500m(limits),Memory 128Mi~512Mi(limits),replicas: 1
|
||
|
||
---
|
||
|
||
## 一、测试环境
|
||
|
||
| 项目 | 配置 |
|
||
|------|------|
|
||
| 服务 | hw_service_go(WebSocket + Opus 音频推送) |
|
||
| 部署 | K8s 单 Pod,1 副本 |
|
||
| CPU limits | 500m(0.5 核) |
|
||
| Memory limits | 512Mi |
|
||
| 硬编码连接上限 | 500 |
|
||
| 测试工具 | Go 压测工具(`test/stress/main.go`) |
|
||
| 测试客户端 | macOS,从公网连接线上服务 |
|
||
|
||
---
|
||
|
||
## 二、测试结果
|
||
|
||
### 2.1 连接容量测试(空闲连接)
|
||
|
||
```
|
||
go run main.go -url wss://..../xiaozhi/v1/ -conns 200 -stories 0 -duration 30s
|
||
```
|
||
|
||
| 指标 | 结果 |
|
||
|------|------|
|
||
| 目标连接 | 200 |
|
||
| 成功连接 | 200 |
|
||
| 握手成功 | 200 |
|
||
| 错误 | 0 |
|
||
|
||
**结论:200 个空闲连接毫无压力,内存不是瓶颈。**
|
||
|
||
### 2.2 并发播放压力测试
|
||
|
||
每个"活跃故事"会触发:Django API 查询 → MP3 下载 → ffmpeg 转码 → Opus 编码 → WebSocket 推帧。
|
||
|
||
| 并发故事数 | 总连接 | 首帧延迟 | 帧数/故事 | 错误 | 状态 |
|
||
|-----------|--------|---------|----------|------|------|
|
||
| 2 | 10 | **2.0s** | 796 | 0 | 轻松 |
|
||
| 5 | 10 | **4.5s** | 796 | 0 | 正常 |
|
||
| 10 | 20 | **8.7s** | 796 | 0 | 吃力但稳 |
|
||
| 20 | 30 | **17.4s** | 796 | 0 | 极限 |
|
||
|
||
### 2.3 关键发现
|
||
|
||
1. **帧数始终稳定 796/故事** — 音频完整交付,零丢帧,服务可靠性极高
|
||
2. **首帧延迟线性增长** — 约 0.85s/并发,纯 CPU 瓶颈(多个 ffmpeg 进程争抢 0.5 核)
|
||
3. **Pod 未触发 OOMKill** — 512Mi 内存对 20 并发播放也够用
|
||
4. **全程零错误** — 无连接断开、无握手失败、无帧丢失
|
||
|
||
---
|
||
|
||
## 三、瓶颈分析
|
||
|
||
```
|
||
单个故事播放的资源消耗链路:
|
||
|
||
Django API (GET) → MP3 下载 (OSS) → ffmpeg 转码 (CPU密集) → Opus 编码 → WebSocket 推帧
|
||
↑
|
||
主要瓶颈
|
||
每个并发故事启动一个 ffmpeg 子进程
|
||
多个 ffmpeg 共享 0.5 核 CPU
|
||
```
|
||
|
||
| 资源 | 是否瓶颈 | 说明 |
|
||
|------|---------|------|
|
||
| **CPU** | **是** | ffmpeg 转码是 CPU 密集型,0.5 核被多个 ffmpeg 进程分时使用 |
|
||
| 内存 | 否 | 20 并发播放未触发 OOM,512Mi 充足 |
|
||
| 网络 | 否 | Opus 帧约 4-7 KB/s/连接,带宽远未饱和 |
|
||
| 连接数 | 否 | 空闲连接 200+ 无压力,硬上限 500 |
|
||
|
||
---
|
||
|
||
## 四、容量结论
|
||
|
||
### 当前单 Pod(0.5 核 CPU, 512Mi, 1 副本)
|
||
|
||
| 指标 | 数值 |
|
||
|------|------|
|
||
| 空闲连接上限 | **200+**(轻松) |
|
||
| 并发播放(体验好,首帧 < 5s) | **~5 个** |
|
||
| 并发播放(可接受,首帧 < 10s) | **~10 个** |
|
||
| 并发播放(极限,首帧 ~17s) | **~20 个** |
|
||
| 瓶颈资源 | CPU(ffmpeg 转码) |
|
||
|
||
---
|
||
|
||
## 五、扩容建议
|
||
|
||
| 方案 | 变更 | 预估并发播放(首帧 < 10s) | 成本 |
|
||
|------|------|------------------------|------|
|
||
| **提 CPU** | limits 500m → 1000m | ~20 个 | 低 |
|
||
| **加副本** | replicas 1 → 2 | ~10 个(负载均衡) | 中 |
|
||
| **两者都做** | 1000m CPU + 2 副本 | **~40 个** | 中 |
|
||
| 垂直扩容 | 2000m CPU + 1Gi 内存 | ~40 个 | 中 |
|
||
|
||
> **推荐方案**:replicas: 2 + CPU limits: 1000m,兼顾高可用与并发能力。
|
||
|
||
---
|
||
|
||
## 六、测试命令参考
|
||
|
||
```bash
|
||
cd hw_service_go/test/stress
|
||
|
||
# 空闲连接容量
|
||
go run main.go -url wss://TARGET/xiaozhi/v1/ -conns 200 -stories 0 -duration 30s
|
||
|
||
# 并发播放(逐步加压)
|
||
go run main.go -url wss://TARGET/xiaozhi/v1/ -conns 10 -stories 2 -duration 60s
|
||
go run main.go -url wss://TARGET/xiaozhi/v1/ -conns 10 -stories 5 -duration 60s
|
||
go run main.go -url wss://TARGET/xiaozhi/v1/ -conns 20 -stories 10 -duration 90s
|
||
go run main.go -url wss://TARGET/xiaozhi/v1/ -conns 30 -stories 20 -duration 120s
|
||
```
|