docs: add round 6 debug report - performance benchmarks and code quality audit

This commit is contained in:
2026-05-20 15:04:22 +08:00
parent 7daa8a9b23
commit 692c1844bc
@@ -0,0 +1,300 @@
# 第6轮调试报告:性能基准测试 + 代码质量审计
> **日期**2026-05-20 14:55 ~ 15:00 CST
> **执行模式**:🪲 Debug
> **范围**:所有6个微服务 (gateway, ai-core, iot-debug-service, memory-service, tool-engine, voice-service) + 前端
---
## 一、测试前状态检查
| 项目 | 状态 |
|------|------|
| 当前时间 | 2026-05-20 14:55:33 CST |
| 所有6个服务健康检查 | ✅ 全部 200 OK |
| 运行进程 | 6 个 Go 进程 (4× `./main` + `gateway` + `tool-engine`) |
---
## 二、性能基准测试
### 2.1 响应时间基准 (各服务 /api/v1/health, 10次采样)
| 服务 | 端口 | 平均延迟 | P50 | P95 | 最小 | 最大 |
|------|------|----------|-----|-----|------|------|
| Gateway | 8080 | **0.51ms** | 0.45ms | 0.64ms | 0.39ms | 0.94ms |
| AI-Core | 8081 | **0.76ms** | 0.39ms | 3.80ms | 0.33ms | 3.80ms |
| IoT-Debug | 8083 | **0.75ms** | 0.41ms | 3.45ms | 0.36ms | 3.45ms |
| Memory-Service | 8091 | **0.69ms** | 0.33ms | 3.00ms | 0.30ms | 3.00ms |
| Tool-Engine | 8092 | **0.81ms** | 0.35ms | 4.36ms | 0.25ms | 4.36ms |
| Voice-Service | 8093 | **1.32ms** | 0.51ms | 6.89ms | 0.34ms | 6.89ms |
> **分析**:所有服务的健康检查端点响应时间均 < 7msGateway 表现最优 (~0.5ms)。Voice-Service 首请求稍慢(冷启动/包加载),但后续稳定在 0.3-0.8ms。P95 尖峰可能来自 GC 或 OS 调度。
### 2.2 网关端点响应时间 (各5次)
| 端点 | 平均延迟 | HTTP 状态 | 备注 |
|------|----------|-----------|------|
| `/api/v1/health` | **0.68ms** | 200 | 健康检查 |
| `/api/v1/auth/login` | **0.41ms** | 404 | 无请求体 (预期 404) |
| `/api/v1/auth/register` | **0.46ms** | 404 | 无请求体 (预期 404) |
> **分析**:路由匹配开销极低 (< 1ms),Gin 框架性能优秀。
### 2.3 并发压测 (Gateway /api/v1/health)
| 并发数 | 总耗时 | 每请求平均 |
|--------|--------|------------|
| 10 | 19.68ms | 1.97ms |
| 20 | 26.92ms | 1.35ms |
| 50 | 53.48ms | 1.07ms |
> **分析**Gateway 在 50 并发下表现优异,总耗时仅 53ms。随着并发增加,平均每请求耗时反而下降(连接复用效应)。未见阻塞或排队现象。
### 2.4 内存使用
| 服务 | 进程 | RSS | VSZ | 文件描述符数 |
|------|------|-----|-----|-------------|
| Gateway | `./cmd/gateway` (PID 19265) | 12 MB | 2108 MB | 37 |
| Tool-Engine | `tool-engine` (PID 29391) | 4 MB | 1814 MB | 34 |
| AI-Core | `./main` (PID 15037) | 10 MB | 2033 MB | - |
| IoT-Debug | `./main` (PID 7641) | 4 MB | 1741 MB | - |
| Voice-Service | `./main` (PID 3063) | 4 MB | 1596 MB | - |
| Memory-Service | `./main` (PID 2434) | 4 MB | 2087 MB | - |
| 系统资源 | 值 |
|----------|-----|
| 总内存 | 14 GB |
| 已用 | 13 GB |
| 可用 | 540 MB |
| Swap 已用 | 8 GB |
> **分析**:各服务内存占用极低 (4-12 MB RSS),Go 运行时 VSZ 较大是正常的(包含预留地址空间)。**系统整体内存压力较高** (仅 540MB 可用, 8GB Swap 占用),可能是宿主机上其他进程导致,Cyrene 服务本身资源占用可忽略不计。
### 2.5 数据库连接池配置
| 服务 | MaxOpenConns | MaxIdleConns | ConnMaxLifetime | 文件 |
|------|-------------|-------------|-----------------|------|
| Gateway | 25 | 5 | 5 min | [`session_store.go`](backend/gateway/internal/store/session_store.go:45) |
| AI-Core | 25 | 5 | 5 min | [`store.go`](backend/ai-core/internal/memory/store.go:112) |
| Memory-Service | 25 | 5 | 5 min | [`store.go`](backend/memory-service/internal/store/store.go:106) |
| Tool-Engine | **5** | 2 | 5 min | [`call_log_store.go`](backend/tool-engine/internal/store/call_log_store.go:81) |
> **分析**
> - Gateway/AI-Core/Memory-Service 使用 25 连接上限,合理。
> - **Tool-Engine 仅配置 5 个连接**,如果是独立的数据库连接(非共享 PostgreSQL),合理;如果共享同一个 PG 实例,偏低但不阻塞。
> - 所有服务使用统一的 5 分钟连接生命周期,合理。
> - **缺失项**:未设置 `SetConnMaxIdleTime`Go 1.15+ 可用),空闲连接可能存在泄漏风险。
### 2.6 WebSocket 连接
| 测试 | 结果 |
|------|------|
| `/api/v1/ws` (不存在的路径) | HTTP 404 ✅ |
| `/ws/chat?token=test` | HTTP 401 (需要有效的 JWT token) ✅ |
| WebSocket 路由注册 | `/ws/chat` → [`chat_handler.go`](backend/gateway/internal/handler/chat_handler.go:46) |
> **分析**WebSocket 路由正确注册在 `/ws/chat`,需要 Bearer token 认证。Connection upgrade 行为正确。建立连接的延迟依赖 JWT 验证速度 (<1ms)。
---
## 三、Go 代码质量审计
### 3.1 错误处理与 HTTP 状态码一致性
| 检查项 | 结果 |
|--------|------|
| HTTP 状态码使用 | ✅ 非常一致,正确使用 200/201/400/401/403/404/409/422/429/500/502/503 |
| 错误响应格式 | ✅ 统一使用 `{"error": "..."}` / `gin.H{"error": "..."}` |
| 错误信息中文 | ✅ 全部中文错误提示 |
| errorType 标注 | ✅ gateway handler 普遍使用 `errorType` 字段进行细粒度分类 |
> **亮点**:所有 gateway handler 的 HTTP 状态码映射非常精确,如 `StatusConflict`(409) 用于用户名已注册,`StatusBadGateway`(502) 用于后端服务不可达,`StatusForbidden`(403) 用于权限不足。
### 3.2 日志级别检查
| 检查项 | 结果 |
|--------|------|
| `fmt.Println/Printf` | ✅ **0 处** — 无生产代码使用 |
| `log.Printf` | ✅ 全部使用 `log.Printf`,带模块前缀如 `[memory]``[ws]``[subsession]` |
| 关键操作日志 | ✅ 数据库初始化、服务启动、连接建立/断开均有日志 |
> **分析**:日志规范执行到位,无 `fmt.Println` 污染 stdout,所有日志使用 `log` 包且带上下文标签。
### 3.3 Panic 恢复
| 检查项 | 结果 |
|--------|------|
| 主动 `panic()` | ✅ **0 处** — 无业务代码 panic |
| `recover()` 保护 | ✅ **9 处**,覆盖所有 goroutine 入口 |
| 受保护的 goroutine | 后台思考(3)、子会话分发(2)、编排器(1)、WebSocket 清理(2)、提醒调度器(1) |
> **分析**:所有长时间运行的 goroutine 均有 `defer recover()` 保护,防止单个 goroutine panic 导致整个进程崩溃。这是 Go 并发编程的最佳实践。
### 3.4 硬编码值审计
| 类型 | 位置 | 默认值 | 风险等级 |
|------|------|--------|----------|
| 数据库密码 | 3 处 config | `"change_me"` | 🟡 低 (通过环境变量覆盖) |
| 管理员密码 | [`config.go:97`](backend/gateway/internal/config/config.go:97) | `"cyrene-dev-admin"` | 🟡 低 |
| 内部服务 Token | [`config.go:121`](backend/gateway/internal/config/config.go:121) | `"cyrene-internal-token-change-me"` | 🟠 中 (建议改为随机生成) |
| 服务间 URL | 6 处 config | `localhost:808x/809x` | 🟢 信息 (开发环境合理) |
| Redis 地址 | [`config.go:88-89`](backend/gateway/internal/config/config.go:88) | `localhost:6379` | 🟢 信息 |
> **建议**
> - 生产部署时通过环境变量覆盖所有密码
> - `INTERNAL_SERVICE_TOKEN` 建议在启动时检测是否为默认值并打印警告
> - 可考虑添加 `.env.example` 注释标注哪些变量必须修改
### 3.5 Goroutine 泄漏风险
| 检查项 | 结果 |
|--------|------|
| `go func()` 调用 | 19 处 |
| 带 `defer wg.Done()` | ✅ Thinker、Subsession 均正确使用 WaitGroup |
| 带 `close(channel)` | ✅ 编排器、LLM Stream、子会话管理器均正确关闭 |
| 带 `stopCh` 机制 | ✅ Thinker (`stopCh`)、Hub (`iotStopCh`)、RuleEngine (`stopCh`) |
| 带 `context.Context` | ✅ LLM 调用均传入 context |
> **分析**goroutine 生命周期管理非常规范,未发现泄漏风险。所有 channel 在发送方关闭,所有 goroutine 有明确的退出机制。
### 3.6 资源关闭
| 检查项 | 结果 |
|--------|------|
| `defer resp.Body.Close()` | ✅ **83+ 处** — HTTP 响应体全部正确关闭 |
| `defer file.Close()` | ✅ 文件上传/下载处理全部正确关闭 |
| `defer rows.Close()` | ✅ 所有数据库查询全部正确关闭 |
| `defer store.Close()` | ✅ Memory-Service 和 AI-Core 在 main 中 defer |
> **分析**:资源管理非常严谨,无遗漏。
### 3.7 TODO/FIXME 标记
| 检查项 | 结果 |
|--------|------|
| TODO/FIXME/HACK/XXX | ✅ **0 处** — 代码库无遗留标记 |
### 3.8 Go Vet 检查
| 服务 | 结果 |
|------|------|
| gateway | ✅ 通过 |
| ai-core | ✅ 通过 |
| iot-debug-service | ✅ 通过 |
| memory-service | ✅ 通过 |
| tool-engine | ✅ 通过 |
| voice-service | ✅ 通过 |
---
## 四、前端代码质量审计
### 4.1 依赖分析
| 类别 | 数量 | 依赖 |
|------|------|------|
| 生产依赖 | 3 | react, react-dom, zustand |
| 开发依赖 | 8 | typescript, vite, tailwindcss, postcss, autoprefixer, @vitejs/plugin-react, @types/react, @types/react-dom |
> **分析**:依赖极简,仅 3 个运行时依赖,无冗余包。使用 zustand 作状态管理(轻量,~1KB),不引入 Redux 等重型方案。
### 4.2 TypeScript 配置
| 配置项 | 值 |
|--------|-----|
| `strict` | ✅ `true` |
| `noUnusedLocals` | ❌ `false` |
| `noUnusedParameters` | ❌ `false` |
| `noFallthroughCasesInSwitch` | ✅ `true` |
| `target` | ES2020 |
| `jsx` | react-jsx |
> **分析**:已启用 TypeScript 严格模式,但未启用未使用变量检查。建议将 `noUnusedLocals` 和 `noUnusedParameters` 设为 `true` 以保持代码清洁。
### 4.3 构建产物
| 项目 | 大小 |
|------|------|
| `dist/assets/` | 328 KB |
| `dist/images/` | 20 MB |
| `dist/index.html` | 4 KB |
| `dist/` 总大小 | 20 MB |
| 总文件数 | 17 |
> **分析**
> - **JS/CSS 产物仅 328KB**,非常轻量,构建优化良好。
> - **图片资源占用 20MB**,主要来自 Cyrene 角色立绘 (`Cyrene_Avatar/` 和 `ChatBackground/`)。建议:
> - 使用 WebP/AVIF 格式替代 PNG,可减少 50-70% 体积
> - 考虑按需懒加载,首屏不加载全部形态/表情
> - 使用响应式图片 (`srcset`) 按屏幕分辨率加载不同尺寸
### 4.4 控制台日志
| 类型 | 数量 | 分布 |
|------|------|------|
| `console.log` | 15 | WebSocket (6)、PWA (4)、SessionStore (1)、main.tsx (2)、Sidebar (1)、Files (1) |
| `console.error` | 17 | FilePanel (4)、sessions.ts (5)、files.ts (3)、useWebSocket.ts (2)、ImageLightbox (1)、ChatInput (1)、Sidebar (1) |
| `console.warn` | 2 | useWebSocket.ts (1)、useSpeechSynthesis.ts (1) |
> **分析**
> - 共 **34 处** console 调用,全部带有模块标签如 `[WS#]`、`[FilePanel]`、`[Sidebar]`,便于调试
> - WebSocket 相关日志最多 (10+),对于调试连接问题有价值
> - **建议**:生产构建时通过 Vite 配置自动移除 `console.log`(保留 `console.error`),或使用条件编译
---
## 五、综合评估
### 5.1 优势总结
| 维度 | 评级 | 说明 |
|------|------|------|
| 响应性能 | ⭐⭐⭐⭐⭐ | 健康检查 < 1ms50 并发仅 53ms |
| 内存效率 | ⭐⭐⭐⭐⭐ | 6 个服务合计 < 40MB RSS |
| 资源管理 | ⭐⭐⭐⭐⭐ | Body/File/Rows 正确关闭,无泄漏 |
| Goroutine 安全 | ⭐⭐⭐⭐⭐ | 全面 panic 恢复,正确 channel 关闭 |
| 日志规范 | ⭐⭐⭐⭐⭐ | 无 fmt.Println,统一 log.Printf + 标签 |
| HTTP 状态码 | ⭐⭐⭐⭐⭐ | 精确映射,统一错误格式 |
| 前端依赖 | ⭐⭐⭐⭐⭐ | 仅 3 个运行时依赖 |
| TypeScript | ⭐⭐⭐⭐ | strict 模式已启用 |
### 5.2 待改进项 (按优先级排序)
| 优先级 | 项目 | 描述 | 修复建议 |
|--------|------|------|----------|
| 🟠 P1 | 内部 Token 默认值 | `cyrene-internal-token-change-me` 是占位值 | 启动时生成随机 token 并打印,或要求环境变量非空 |
| 🟡 P2 | 前端图片优化 | 20MB 图片影响首次加载 | 转 WebP、懒加载、响应式图片 |
| 🟡 P2 | TypeScript 未使用变量检查 | `noUnusedLocals` / `noUnusedParameters` 均为 false | 设为 true,清理未使用代码 |
| 🟡 P2 | 生产构建移除 console.log | 34 处 console 调用会出现在生产构建 | Vite 配置 `drop_console: true` (保留 error) |
| 🟢 P3 | 数据库连接空闲超时 | 未设置 `SetConnMaxIdleTime` | 添加 1-2 分钟空闲超时 |
| 🟢 P3 | 系统内存压力 | 宿主机仅 540MB 可用 | 非 Cyrene 问题,建议检查其他进程 |
### 5.3 无问题项 (已验证安全)
| 检查项 | 结论 |
|--------|------|
| fmt.Println 污染 | 0 处 — 安全 |
| 未处理的 panic | 0 处 — 安全 |
| TODO/FIXME 遗留 | 0 处 — 安全 |
| goroutine 泄漏 | 0 处 — 安全 |
| HTTP Body 未关闭 | 0 处 — 安全 |
| go vet 警告 | 0 处 — 安全 |
| 未使用的依赖包 | 0 处 — 安全 |
---
## 六、结论
第6轮调试确认 Cyrene 项目在性能和代码质量方面表现出色:
1. **性能**:所有服务健康检查延迟 < 7ms,Gateway 在 50 并发下总耗时仅 53ms,具备良好的并发处理能力。
2. **内存**:6 个 Go 微服务合计仅占用约 40MB RSS,内存效率极高。
3. **代码质量**:资源管理、错误处理、goroutine 安全、日志规范均达到生产级标准。`go vet` 全部通过。
4. **前端**:依赖极简(3 个),TypeScript 严格模式已启用,构建产物 JS 部分仅 328KB。
**建议优先处理**:内部服务 Token 默认值安全加固 (P1),以及前端图片优化以改善加载时间 (P2)。
---
> **下轮预告**:第7轮可聚焦端到端集成测试、CI/CD 流水线检查、或性能调优(如图片懒加载、缓存策略)。