repair-agent 134ccb70f3
All checks were successful
Build and Deploy Backend / build-and-deploy (push) Successful in 5m41s
fix 音频并发优化
2026-03-03 17:21:46 +08:00

122 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# hw_service_go 并发压力测试报告
> 测试时间2026-03-03
> 测试目标:`wss://qiyuan-rtc-api.airlabs.art/xiaozhi/v1/`
> Pod 配置:单 PodCPU 100m~500mlimitsMemory 128Mi~512Milimitsreplicas: 1
---
## 一、测试环境
| 项目 | 配置 |
|------|------|
| 服务 | hw_service_goWebSocket + Opus 音频推送) |
| 部署 | K8s 单 Pod1 副本 |
| CPU limits | 500m0.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 并发播放未触发 OOM512Mi 充足 |
| 网络 | 否 | Opus 帧约 4-7 KB/s/连接,带宽远未饱和 |
| 连接数 | 否 | 空闲连接 200+ 无压力,硬上限 500 |
---
## 四、容量结论
### 当前单 Pod0.5 核 CPU, 512Mi, 1 副本)
| 指标 | 数值 |
|------|------|
| 空闲连接上限 | **200+**(轻松) |
| 并发播放(体验好,首帧 < 5s | **~5 ** |
| 并发播放可接受首帧 < 10s | **~10 ** |
| 并发播放极限首帧 ~17s | **~20 ** |
| 瓶颈资源 | CPUffmpeg 转码 |
---
## 五、扩容建议
| 方案 | 变更 | 预估并发播放首帧 < 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
```