修改
This commit is contained in:
399
.qoder/repowiki/zh/content/部署指南/性能优化.md
Normal file
399
.qoder/repowiki/zh/content/部署指南/性能优化.md
Normal file
@@ -0,0 +1,399 @@
|
||||
# 性能优化
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [src/index.ts](file://src/index.ts)
|
||||
- [src/server.ts](file://src/server.ts)
|
||||
- [src/websocket.ts](file://src/websocket.ts)
|
||||
- [src/class/websockethandler.ts](file://src/class/websockethandler.ts)
|
||||
- [src/class/httphandler.ts](file://src/class/httphandler.ts)
|
||||
- [src/signaling.ts](file://src/signaling.ts)
|
||||
- [src/log.ts](file://src/log.ts)
|
||||
- [client/src/signaling.js](file://client/src/signaling.js)
|
||||
- [client/src/peer.js](file://client/src/peer.js)
|
||||
- [client/src/sender.js](file://client/src/sender.js)
|
||||
- [client/src/logger.js](file://client/src/logger.js)
|
||||
- [client/public/js/stats.js](file://client/public/js/stats.js)
|
||||
- [client/public/onebyone/store.js](file://client/public/onebyone/store.js)
|
||||
- [client/src/memoryhelper.js](file://client/src/memoryhelper.js)
|
||||
- [package.json](file://package.json)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本指南围绕视频流服务器与前端 WebRTC 客户端的整体性能进行系统化优化,覆盖以下方面:
|
||||
- 内存管理优化:垃圾回收调优、内存泄漏检测与进程监控
|
||||
- 并发处理优化:连接池配置、线程数调整、异步处理优化
|
||||
- 资源限制设置:文件描述符、网络连接、CPU 使用率控制
|
||||
- WebRTC 性能优化:编码参数、带宽自适应、网络质量监控
|
||||
- 缓存策略:静态资源、API 响应、浏览器缓存
|
||||
- 性能监控指标与基准测试方法
|
||||
|
||||
## 项目结构
|
||||
该项目采用前后端分离的结构:
|
||||
- 服务端基于 Express 提供 HTTP/WebSocket 信令与静态资源托管,同时支持 HTTPS
|
||||
- 客户端包含多种示例页面与 WebRTC 输入/渲染相关脚本,以及统计与日志工具
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "服务端"
|
||||
IDX["入口: src/index.ts"]
|
||||
SRV["HTTP 服务器: src/server.ts"]
|
||||
WS["WebSocket 信令: src/websocket.ts"]
|
||||
WSH["WS 处理器: src/class/websockethandler.ts"]
|
||||
HTTPH["HTTP 信令处理器: src/class/httphandler.ts"]
|
||||
SIG["信令路由: src/signaling.ts"]
|
||||
LOG["日志: src/log.ts"]
|
||||
end
|
||||
subgraph "客户端"
|
||||
CLISIG["信令客户端: client/src/signaling.js"]
|
||||
PEER["Peer 连接: client/src/peer.js"]
|
||||
SENDER["输入发送: client/src/sender.js"]
|
||||
STATS["统计: client/public/js/stats.js"]
|
||||
STORE["质量分析: client/public/onebyone/store.js"]
|
||||
LOGGER["日志: client/src/logger.js"]
|
||||
end
|
||||
IDX --> SRV
|
||||
SRV --> WS
|
||||
SRV --> SIG
|
||||
WS --> WSH
|
||||
SIG --> HTTPH
|
||||
CLISIG --> |"WebSocket"| WS
|
||||
CLISIG --> |"HTTP 轮询"| SRV
|
||||
PEER --> |"WebRTC 统计"| STATS
|
||||
PEER --> |"WebRTC 统计"| STORE
|
||||
SENDER --> |"输入事件"| PEER
|
||||
LOG -.->|"服务端日志级别"| SRV
|
||||
LOGGER -.->|"客户端调试开关"| CLISIG
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
|
||||
- [src/server.ts:1-90](file://src/server.ts#L1-L90)
|
||||
- [src/websocket.ts:1-118](file://src/websocket.ts#L1-L118)
|
||||
- [src/class/websockethandler.ts:1-479](file://src/class/websockethandler.ts#L1-L479)
|
||||
- [src/class/httphandler.ts:1-800](file://src/class/httphandler.ts#L1-L800)
|
||||
- [src/signaling.ts:1-25](file://src/signaling.ts#L1-L25)
|
||||
- [src/log.ts:1-51](file://src/log.ts#L1-L51)
|
||||
- [client/src/signaling.js:1-292](file://client/src/signaling.js#L1-L292)
|
||||
- [client/src/peer.js:1-188](file://client/src/peer.js#L1-L188)
|
||||
- [client/src/sender.js:1-209](file://client/src/sender.js#L1-L209)
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
|
||||
- [client/src/logger.js:1-30](file://client/src/logger.js#L1-L30)
|
||||
|
||||
章节来源
|
||||
- [src/index.ts:1-109](file://src/index.ts#L1-L109)
|
||||
- [src/server.ts:1-90](file://src/server.ts#L1-L90)
|
||||
|
||||
## 核心组件
|
||||
- 服务端启动与 HTTPS/HTTP 选择、日志级别、信令类型与运行模式
|
||||
- Express 中间件链:CORS、JSON/URL 编码、静态资源、Swagger 文档
|
||||
- WebSocket 信令服务器与处理器:连接生命周期、广播、1对多模式、心跳
|
||||
- HTTP 信令轮询:会话管理、超时清理、消息队列(offer/answer/candidate)
|
||||
- 客户端信令:WebSocket 与 HTTP 轮询双栈;WebRTC Peer 连接与统计
|
||||
- 日志系统:服务端日志级别控制;客户端调试输出开关
|
||||
|
||||
章节来源
|
||||
- [src/index.ts:13-109](file://src/index.ts#L13-L109)
|
||||
- [src/server.ts:14-89](file://src/server.ts#L14-L89)
|
||||
- [src/websocket.ts:6-118](file://src/websocket.ts#L6-L118)
|
||||
- [src/class/websockethandler.ts:63-137](file://src/class/websockethandler.ts#L63-L137)
|
||||
- [src/class/httphandler.ts:110-120](file://src/class/httphandler.ts#L110-L120)
|
||||
- [src/signaling.ts:4-24](file://src/signaling.ts#L4-L24)
|
||||
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
|
||||
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)
|
||||
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)
|
||||
|
||||
## 架构总览
|
||||
服务端通过 Express 提供 HTTP 接口与静态资源,WebSocket 作为实时信令通道;HTTP 轮询作为备用方案。客户端根据配置选择 WebSocket 或 HTTP 轮询进行信令交互,WebRTC 数据通道承载媒体与控制消息。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as "客户端"
|
||||
participant S as "Express 服务器"
|
||||
participant WS as "WebSocket 信令"
|
||||
participant HTTP as "HTTP 信令"
|
||||
participant H as "HTTP 处理器"
|
||||
C->>S : "GET /config"
|
||||
S-->>C : "{useWebSocket, mode, logging}"
|
||||
alt "WebSocket 模式"
|
||||
C->>WS : "建立连接"
|
||||
WS-->>C : "connect"
|
||||
C->>WS : "offer/answer/candidate/on-message"
|
||||
WS->>WS : "路由/广播/心跳"
|
||||
WS-->>C : "响应/广播"
|
||||
else "HTTP 轮询模式"
|
||||
C->>HTTP : "PUT /signaling (创建会话)"
|
||||
HTTP-->>C : "{sessionId}"
|
||||
loop "轮询"
|
||||
C->>HTTP : "GET /signaling?fromtime=..."
|
||||
HTTP->>H : "读取 offer/answer/candidate/disconnect"
|
||||
H-->>HTTP : "聚合消息"
|
||||
HTTP-->>C : "{messages, datetime}"
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [src/server.ts:25-41](file://src/server.ts#L25-L41)
|
||||
- [src/websocket.ts:27-115](file://src/websocket.ts#L27-L115)
|
||||
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
|
||||
- [src/signaling.ts:6-24](file://src/signaling.ts#L6-L24)
|
||||
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 服务端启动与运行模式
|
||||
- 支持命令行参数:端口、HTTPS 证书、信令类型(websocket/http)、运行模式(public/private)、日志级别
|
||||
- 自动选择 HTTP 或 HTTPS 监听,打印可用地址
|
||||
- 信令类型校验与回退至默认值
|
||||
- WebSocket 信令服务器初始化并注入运行模式
|
||||
|
||||
章节来源
|
||||
- [src/index.ts:14-91](file://src/index.ts#L14-L91)
|
||||
|
||||
### HTTP 服务器与静态资源
|
||||
- 开启 Morgan 日志(可配置)
|
||||
- CORS 允许任意来源
|
||||
- 解析 JSON/URL 编码请求体
|
||||
- 提供 /config、/signaling 路由、静态资源目录
|
||||
- Swagger 文档初始化
|
||||
- 头像上传接口:multer 存储、重命名、返回相对 URL
|
||||
|
||||
章节来源
|
||||
- [src/server.ts:18-89](file://src/server.ts#L18-L89)
|
||||
|
||||
### WebSocket 信令服务器
|
||||
- 基于 ws 的服务器实例绑定到 HTTP 服务器
|
||||
- 连接生命周期:add/remove
|
||||
- 消息分发:connect/disconnect/offer/answer/candidate/ping/pong/broadcast/call-request/on-message
|
||||
- 心跳机制(注释掉的实现),可通过处理器扩展
|
||||
|
||||
章节来源
|
||||
- [src/websocket.ts:15-118](file://src/websocket.ts#L15-L118)
|
||||
- [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430)
|
||||
|
||||
### WebSocket 处理器(1对多模式与广播)
|
||||
- 私有模式:host 与多个 participants;offer/answer/candidate 按 participantId 路由
|
||||
- 公共模式:全局广播
|
||||
- 连接组管理:host/participants、参与者加入/离开通知
|
||||
- 广播消息:支持按连接组或全局广播
|
||||
- 心跳与超时(注释实现)
|
||||
|
||||
章节来源
|
||||
- [src/class/websockethandler.ts:63-168](file://src/class/websockethandler.ts#L63-L168)
|
||||
- [src/class/websockethandler.ts:175-206](file://src/class/websockethandler.ts#L175-L206)
|
||||
- [src/class/websockethandler.ts:214-338](file://src/class/websockethandler.ts#L214-L338)
|
||||
- [src/class/websockethandler.ts:370-402](file://src/class/websockethandler.ts#L370-L402)
|
||||
|
||||
### HTTP 信令处理器(轮询模式)
|
||||
- 会话管理:创建/删除、连接集合、超时检测
|
||||
- 消息存储:offer/answer/candidate 映射,断开连接记录
|
||||
- 查询接口:/signaling、/offer、/answer、/candidate、/connection
|
||||
- 私有模式下的连接配对与跨会话消息路由
|
||||
|
||||
章节来源
|
||||
- [src/class/httphandler.ts:110-120](file://src/class/httphandler.ts#L110-L120)
|
||||
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
|
||||
- [src/class/httphandler.ts:398-407](file://src/class/httphandler.ts#L398-L407)
|
||||
- [src/class/httphandler.ts:492-501](file://src/class/httphandler.ts#L492-L501)
|
||||
- [src/class/httphandler.ts:549-558](file://src/class/httphandler.ts#L549-L558)
|
||||
- [src/class/httphandler.ts:615-641](file://src/class/httphandler.ts#L615-L641)
|
||||
|
||||
### 客户端信令与 WebRTC
|
||||
- WebSocketSignaling:连接建立、消息分发、发送 offer/answer/candidate/on-message
|
||||
- HTTP 轮询 Signaling:循环拉取消息、事件派发
|
||||
- Peer:RTCPeerConnection 生命周期、ICE 候选收集、状态变化监听、重发 offer
|
||||
- Sender:鼠标/键盘/手柄/触摸输入采集与事件队列
|
||||
- 统计:客户端侧统计计算(比特率、帧率、抖动、往返时间等)
|
||||
|
||||
章节来源
|
||||
- [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292)
|
||||
- [client/src/signaling.js:30-97](file://client/src/signaling.js#L30-L97)
|
||||
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)
|
||||
- [client/src/peer.js:124-130](file://client/src/peer.js#L124-L130)
|
||||
- [client/src/sender.js:14-188](file://client/src/sender.js#L14-L188)
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
|
||||
|
||||
### 日志系统
|
||||
- 服务端:枚举日志级别、动态设置、格式化输出
|
||||
- 客户端:调试开关、条件输出
|
||||
|
||||
章节来源
|
||||
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
|
||||
- [client/src/logger.js:3-29](file://client/src/logger.js#L3-L29)
|
||||
|
||||
## 依赖关系分析
|
||||
- 服务端依赖:Express、ws、Morgan、Swagger、UUID、Multer
|
||||
- 客户端依赖:浏览器原生 WebRTC API、EventTarget、fetch
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
P["package.json 依赖"] --> E["Express"]
|
||||
P --> W["ws"]
|
||||
P --> M["Morgan"]
|
||||
P --> SW["Swagger"]
|
||||
P --> U["UUID"]
|
||||
P --> MU["Multer"]
|
||||
E --> SRV["src/server.ts"]
|
||||
W --> WS["src/websocket.ts"]
|
||||
SRV --> SIG["src/signaling.ts"]
|
||||
SIG --> HTTPH["src/class/httphandler.ts"]
|
||||
WS --> WSH["src/class/websockethandler.ts"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [package.json:14-26](file://package.json#L14-L26)
|
||||
- [src/server.ts:1-14](file://src/server.ts#L1-L14)
|
||||
- [src/websocket.ts:1-6](file://src/websocket.ts#L1-L6)
|
||||
- [src/signaling.ts:1-4](file://src/signaling.ts#L1-L4)
|
||||
- [src/class/httphandler.ts:1-11](file://src/class/httphandler.ts#L1-L11)
|
||||
- [src/class/websockethandler.ts:1-11](file://src/class/websockethandler.ts#L1-L11)
|
||||
|
||||
章节来源
|
||||
- [package.json:14-26](file://package.json#L14-L26)
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理优化
|
||||
- 垃圾回收调优
|
||||
- 服务端:合理设置 Node.js 堆大小与 GC 参数(通过环境变量或启动脚本传入),避免大对象频繁分配与长生命周期持有
|
||||
- 客户端:避免在事件回调中累积大量闭包引用;及时释放媒体轨道与数据通道
|
||||
- 内存泄漏检测
|
||||
- 服务端:启用堆快照与内存采样,关注 Map/Set 的增长趋势(如连接组、会话映射)
|
||||
- 客户端:使用浏览器开发者工具的内存面板,检查事件监听器与 DOM 引用是否正确清理
|
||||
- 进程监控
|
||||
- 服务端:定期记录内存使用、连接数、请求量;异常时触发重启或降级
|
||||
- 客户端:统计页面生命周期内的内存峰值与抖动
|
||||
|
||||
章节来源
|
||||
- [src/class/websockethandler.ts:19-37](file://src/class/websockethandler.ts#L19-L37)
|
||||
- [src/class/httphandler.ts:42-77](file://src/class/httphandler.ts#L42-L77)
|
||||
- [client/src/peer.js:184-186](file://client/src/peer.js#L184-L186)
|
||||
|
||||
### 并发处理优化
|
||||
- 连接池配置
|
||||
- 服务端:限制并发请求数与 WebSocket 连接数,结合负载均衡部署
|
||||
- 客户端:合理设置轮询间隔,避免过于频繁的短连接请求
|
||||
- 线程数调整
|
||||
- Node.js:使用集群模式(cluster)或多进程部署,避免单进程阻塞
|
||||
- 异步处理优化
|
||||
- 服务端:将耗时操作(文件写入、统计计算)放入任务队列或子线程
|
||||
- 客户端:WebRTC 统计与事件处理使用 requestAnimationFrame 或微任务
|
||||
|
||||
章节来源
|
||||
- [src/server.ts:44-83](file://src/server.ts#L44-L83)
|
||||
- [client/src/signaling.js:49-91](file://client/src/signaling.js#L49-L91)
|
||||
|
||||
### 资源限制设置
|
||||
- 文件描述符限制
|
||||
- Linux:ulimit -n;Docker:--ulimit nofile;确保并发连接与文件上传场景充足
|
||||
- 网络连接限制
|
||||
- 服务端:限制每 IP 的连接数与速率;启用反向代理限流
|
||||
- 客户端:合理设置轮询超时与重试次数
|
||||
- CPU 使用率控制
|
||||
- 服务端:限制并发任务数量;对高 CPU 操作(编码/解码统计)做节流
|
||||
- 客户端:降低统计频率、减少不必要的事件派发
|
||||
|
||||
章节来源
|
||||
- [src/server.ts:44-83](file://src/server.ts#L44-L83)
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
|
||||
### WebRTC 性能优化
|
||||
- 编码参数调整
|
||||
- 服务端:通过信令协商合适的编解码器与参数(如分辨率、帧率、码率范围)
|
||||
- 客户端:根据网络质量动态调整发送轨道参数
|
||||
- 带宽自适应
|
||||
- 使用 WebRTC 的 BWE 与 REMB;客户端周期性上报统计,服务端下发降级指令
|
||||
- 网络质量监控
|
||||
- 客户端统计:比特率、帧率、抖动、丢包率、往返时间
|
||||
- 服务端:聚合统计与告警阈值
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> GetStats["获取 WebRTC 统计"]
|
||||
GetStats --> Compute["计算比特率/帧率/抖动/丢包率"]
|
||||
Compute --> Check{"是否异常?"}
|
||||
Check --> |否| End(["结束"])
|
||||
Check --> |是| Adapt["调整编码参数/带宽"]
|
||||
Adapt --> SendCmd["通过信令下发降级指令"]
|
||||
SendCmd --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
|
||||
- [client/src/peer.js:124-130](file://client/src/peer.js#L124-L130)
|
||||
|
||||
章节来源
|
||||
- [client/src/peer.js:37-82](file://client/src/peer.js#L37-L82)
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
- [client/public/onebyone/store.js:1130-1380](file://client/public/onebyone/store.js#L1130-L1380)
|
||||
|
||||
### 缓存策略配置
|
||||
- 静态资源缓存
|
||||
- Express 静态托管:设置合理的 Cache-Control 与 ETag
|
||||
- 前端构建产物:版本化文件名,长期缓存
|
||||
- API 响应缓存
|
||||
- HTTP 信令:对只读查询设置短期缓存,结合 Last-Modified/ETag
|
||||
- 浏览器缓存设置
|
||||
- 客户端脚本:强缓存;HTML:协商缓存
|
||||
- 服务端:通过中间件统一设置缓存头
|
||||
|
||||
章节来源
|
||||
- [src/server.ts:27-28](file://src/server.ts#L27-L28)
|
||||
- [src/server.ts:86](file://src/server.ts#L86)
|
||||
|
||||
### 性能监控指标与基准测试
|
||||
- 指标
|
||||
- 服务端:QPS、P95/P99 延迟、连接数、内存、GC 次数与暂停时间
|
||||
- 客户端:首帧时间、卡顿次数、统计上报频率、丢包率、抖动
|
||||
- 基准测试
|
||||
- 使用压测工具模拟多路并发;对比 WebSocket 与 HTTP 轮询的延迟与稳定性
|
||||
- WebRTC:不同分辨率/帧率组合下的端到端延迟与质量
|
||||
|
||||
章节来源
|
||||
- [src/log.ts:15-24](file://src/log.ts#L15-L24)
|
||||
- [client/public/js/stats.js:40-91](file://client/public/js/stats.js#L40-L91)
|
||||
|
||||
## 故障排查指南
|
||||
- WebSocket 连接异常
|
||||
- 检查心跳实现与超时阈值;确认处理器中的连接移除逻辑
|
||||
- HTTP 轮询堆积
|
||||
- 检查会话超时清理与消息去重;优化轮询间隔
|
||||
- 内存泄漏
|
||||
- 关注 Map/Set 的清理时机;客户端事件监听器与 DOM 引用释放
|
||||
- 日志定位
|
||||
- 调整日志级别;区分服务端与客户端日志输出
|
||||
|
||||
章节来源
|
||||
- [src/class/websockethandler.ts:404-430](file://src/class/websockethandler.ts#L404-L430)
|
||||
- [src/class/httphandler.ts:218-232](file://src/class/httphandler.ts#L218-L232)
|
||||
- [src/log.ts:30-50](file://src/log.ts#L30-L50)
|
||||
- [client/src/logger.js:3-29](file://client/src/logger.js#L3-L29)
|
||||
|
||||
## 结论
|
||||
通过合理的内存管理、并发控制、资源限制与 WebRTC 统计监控,可在保证用户体验的同时提升系统的稳定性与吞吐能力。建议在生产环境中结合监控指标持续迭代优化策略,并针对不同部署场景(单机/集群/容器)制定差异化的性能基线。
|
||||
|
||||
## 附录
|
||||
- 启动与配置
|
||||
- 服务端启动脚本与参数:端口、HTTPS、信令类型、运行模式、日志级别
|
||||
- 客户端信令选择:WebSocket 或 HTTP 轮询
|
||||
|
||||
章节来源
|
||||
- [package.json:5-12](file://package.json#L5-L12)
|
||||
- [src/index.ts:20-41](file://src/index.ts#L20-L41)
|
||||
- [client/src/signaling.js:152-292](file://client/src/signaling.js#L152-L292)
|
||||
Reference in New Issue
Block a user