JooLun Plus 百科 ⬇ 源码下载

04.19 分布式直播 WebSocket 架构说明

102353 于 2026-10-17 14:14:33 +08:00 修改了此页面

分布式直播 WebSocket 架构说明

1. 方案目标

直播 WebSocket 服务在多节点部署场景下,需要具备以下能力:

  • 多节点广播消息一致投递
  • 跨节点重复登录踢线
  • 全局在线状态统一统计
  • 房间状态跨节点同步
  • 房间下线后所有节点统一清理连接
  • 商品讲解状态跨节点一致

直播 WebSocket 采用如下方案:

本地 Session + Redis 在线态 + Redis 状态中心 + Redis Pub/Sub 事件总线

2. 设计原则

  • WebSocket Session 只保存在本机内存,不能跨 JVM 共享
  • 所有跨节点共享状态统一存放到 Redis
  • 所有跨节点控制动作统一通过 Redis Pub/Sub 分发
  • 本地 Map、队列、短缓存只作为本节点投递与性能优化层,不作为唯一状态源
  • 节点间不直接互调 WebSocket 内存结构,统一通过 Redis 解耦

3. 总体架构

3.1 三层结构

分布式直播 WebSocket 架构分为三层:

  1. 本地连接层
    每个节点仅维护自己持有的真实 WebSocket Session,例如用户连接 Map、主播连接 Map、房间消息队列、主播消息队列等。

  2. 分布式状态层
    Redis 作为跨节点共享状态中心,统一保存:

    • 用户在线连接元数据
    • 主播在线连接元数据
    • 房间在线用户集合
    • 房间在线主播集合
    • 全局用户连接集合
    • 全局主播连接集合
    • 房间状态
    • 商品讲解状态
  3. 分布式事件层
    Redis Pub/Sub 作为跨节点事件总线,负责广播、踢线、房间清理等事件的跨节点分发。

3.2 方案定位

该方案属于共享状态 + 事件总线模式,适用于多节点部署的实时通信场景。

方案边界如下:

  • WebSocket 长连接落在具体节点上
  • 节点之间不共享 Session 对象
  • 统一通过 Redis 共享状态、传递控制事件

4. 核心组件

  • com.joolun.cloud.live.admin.config.LiveWsRedisConfig
  • com.joolun.cloud.live.admin.distribute.LiveWsConstants
  • com.joolun.cloud.live.admin.distribute.LiveWsConnectionInfo
  • com.joolun.cloud.live.admin.distribute.LiveWsEvent
  • com.joolun.cloud.live.admin.distribute.LiveWsEventType
  • com.joolun.cloud.live.admin.distribute.LiveWsEventPublisher
  • com.joolun.cloud.live.admin.distribute.LiveWsEventSubscriber
  • com.joolun.cloud.live.admin.distribute.LiveWsNodeService
  • com.joolun.cloud.live.admin.distribute.LiveWsPresenceService
  • com.joolun.cloud.live.admin.distribute.LiveWsStateService
  • com.joolun.cloud.live.admin.socket.LiveUserWebSocketServer
  • com.joolun.cloud.live.admin.socket.LiveAnchorWebSocketServer
  • com.joolun.cloud.live.admin.controller.LiveRoomController

5. Redis 数据模型

5.1 在线连接 Key

  • 用户连接:live:ws:user:{tenantId}:{roomId}:{userId}
  • 主播连接:live:ws:anchor:{tenantId}:{roomId}:{userId}

连接元数据主要字段:

  • nodeId
  • sessionId
  • tenantId
  • roomId
  • userId
  • updatedAt

5.2 在线集合 Key

  • 房间用户集合:live:ws:room:users:{tenantId}:{roomId}
  • 房间主播集合:live:ws:room:anchors:{tenantId}:{roomId}
  • 全局用户集合:live:ws:users
  • 全局主播集合:live:ws:anchors

5.3 业务状态 Key

  • 商品讲解状态:live:ws:product:explain:{tenantId}:{roomId}:{spuId}
  • 房间状态:live:ws:room:status:{tenantId}:{roomId}

6. 事件模型

6.1 Pub/Sub 通道

  • 统一通道:live:ws:event

6.2 事件类型

  • USER_BROADCAST
  • ANCHOR_BROADCAST
  • USER_COUNT_CHANGED
  • KICK_USER
  • KICK_ANCHOR
  • CLEANUP_USERS
  • CLEANUP_ANCHORS

6.3 事件职责

  • USER_BROADCAST:将房间消息投递到所有节点的本地用户连接
  • ANCHOR_BROADCAST:将主播相关消息投递到所有节点的本地主播连接
  • USER_COUNT_CHANGED:同步房间在线人数变化
  • KICK_USER / KICK_ANCHOR:按 nodeId + sessionId 精准关闭旧连接
  • CLEANUP_USERS / CLEANUP_ANCHORS:通知所有节点清理指定房间本地连接

7. 关键流程

7.1 用户连接建立

  1. 校验全局连接限制
    基于 Redis 全局用户集合统计。
  2. 校验房间有效性
  3. 处理重复登录
    查询 Redis 历史连接;如旧连接位于其他节点,则发布踢线事件。
  4. 注册本地 Session
  5. 注册 Redis 在线态
    包括连接 Hash、房间集合、全局集合。
  6. 推送连接成功消息和在线人数变更消息

7.2 主播连接建立

  1. 校验全局主播连接限制
  2. 校验直播间与主播权限
  3. 处理主播重复登录
  4. 注册本地 Session 与 Redis 在线态
  5. 同步房间状态到 Redis
  6. 满足开播条件时,更新房间状态为 LIVING

7.3 心跳与失效清理

  • 本地心跳任务定期扫描本节点连接
  • 活跃连接刷新 Redis 连接信息时间戳或 TTL
  • 失效连接同时清理本地内存与 Redis 在线态

7.4 房间下线

管理端执行 /liveroom/offline 后,依次处理:

  1. 广播房间下线状态
  2. 发布 CLEANUP_USERS
  3. 发布 CLEANUP_ANCHORS
  4. 更新数据库直播间状态

7.5 商品讲解状态同步

  • 商品讲解状态写库后同步写入 Redis
  • 各节点处理讲解消息时优先读取 Redis 状态
  • 本地 PROD_EXPLAIN_CACHE 仅保留为短期性能缓存

7.6 房间状态同步

  • 主播连接、开播、停播、结束时同步更新 Redis 房间状态
  • 房间有效性优先基于 Redis 状态判断
  • 本地 ROOM_STATUS_CACHE 仅作为降级缓存

8. 节点本地结构说明

以下本地结构仍然保留,用于节点内连接管理、消息投递和性能优化:

  • LIVE_USER_MAP
  • LIVE_ANCHOR_MAP
  • ROOM_MESSAGE_QUEUE
  • ANCHOR_MSG_QUEUE
  • ROOM_SESSION_CACHE
  • ROOM_STATUS_CACHE
  • PROD_EXPLAIN_CACHE

保留原因:

  • WebSocket Session 必须由当前节点持有
  • 本地批量投递可以降低频繁跨线程发送的成本
  • 短缓存可以减少 Redis 与数据库压力

9. 适用边界

该方案适用于:

  • 多节点直播服务部署
  • 房间消息广播
  • 用户与主播跨节点连接管理
  • 在线状态统一统计
  • 房间状态与商品讲解状态一致性控制

如需继续扩展到更大规模实时场景,可进一步引入专用实时网关或独立消息总线。