skeyevss-performance 国标设备通道有界Channel与并发容器容量代码设计
06 有界 Channel 与并发容器容量
试用安装包下载 | SMS | 在线演示
项目源码地址:https://github.com/openskeye/go-vss
背景
高并发服务中无界队列会在故障或下游变慢时把内存耗尽;小队列则频繁阻塞生产者。并发 Map 若频繁扩容也会带来 CPU 与 GC 压力。VSS 在ServiceContext初始化时为 channel 与xmap指定了统一的容量策略。
项目中的做法
1. 有界 channel:多数为 100
例如SipSendCatalog、SipSendVideoLiveInvite、WSProc各通道、SipLog等均为make(chan T, 100)。
含义:
- 背压:当
SendLogic处理不过来时,写入方会阻塞在 send(或可选用select+default丢弃——当前以阻塞为主,依赖上游超时)。 - 边界可预期:最坏情况下队列中待处理消息条数有上限,便于估算内存(每条消息指针 + 负载)。
2.xmap/set初始容量:1000 量级
如SipCatalogLoopMap、AckRequestMap、PubStreamExistsState、InviteRequestState等使用1000作为预分配 hint(具体以service_context.go为准)。
- 减少 rehash / 扩容:设备与流规模在千级时,命中预设桶大小可降低分配次数。
- xmap不是硬性上限:
xmap仍可增长;若单机万路以上,应结合监控观察Len()与内存。
要点
- 调大 channel:信令尖峰仍丢包时,可先调大缓冲换时间;但若持续满载,应加机器或优化单条处理耗时。
- 调大 map hint:在已知设备数规模时,把 hint 调到1.2× 预期设备数可减少扩容;过大则浪费初始内存。
- 泄漏排查:
AckRequestMap、SipCatalogLoopMap等若未 Remove,Map 调涨——配合 SSE状态中的计数做告警。
相关代码路径
core/app/sev/vss/internal/svc/service_context.go
