← 每日面试题 学习看板

设计一个支持万人在线的语音聊天室,如何保证房间状态(如麦位信息、在线人数)的实时一致性?

面试题/01实践场景题/实践场景题目/场景与业务实践/设计一个支持万人在线的语音聊天室,如何保证房间状态(如麦位信息、在线人数)的实时一致性?.md

面试记录 2026-10-14

题目:设计一个支持万人在线的语音聊天室,如何保证房间状态(如麦位信息、在线人数)的实时一致性?

难度:high

标签:practice/business, architecture/realtime

评分:⭐⭐⭐⭐☆(4/5)

我的回答

直播间这个东西本身就是一个独立的个体。然后直播间状态、麦位信息、在线人数这些,属于直播间个人的、直播间的属性,独立的进行维护。当用户上线或者申请麦位的时候,检查直播间属性上的值,然后进行更新。这个更新使用 Redis 更新,然后同步的展现就可以了。

用户上线的时候,对应的用户在线人数进行原子增,就可以更新上线在线的人数。当用户下线的时候,对应的更新对应的 Redis 就可以实现了。有时候为了保证业务更新,可能会用到 MQ。当用户上线下线的时候,发对应的消息到 MQ,然后监听 MQ 的变更,对应的去更新房间状态,来达到数据的最终一致性;

万人直播间的数据更新,直接用 Redis 本身就可以,并不一定需要 MQ 再去异步处理。在 MQ 异步处理可以提升它更高的兼容性,但是 Redis 本身万人直播间的更新就可以扛得住。新用户获取信息的时候直接获取直播间的信息,这个信息的更新通过长连接,进行对应的实时更新,或者使用服务端推送给客户端进行更新;但是不能使用客户端轮询,这样的客户端轮询产生的并发会让业务服务器崩溃

点评

优点:

不足:

补充:

完整讲解

第一部分:知识重点剖析

核心考点定位:考察"分布式实时系统"的设计能力——状态存储、广播机制、一致性模型三者的权衡。

知识点拆解:

  1. 系统架构分层:
  1. 状态存储设计:
  1. 广播机制:
  1. 麦位管理的复杂性:
  1. 在线人数统计:
  1. 实时同步协议:
  1. 一致性模型:

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 万人在线的 WebSocket 连接怎么横向扩展?
  1. 麦位申请高并发怎么保证原子性?
  1. 强一致和最终一致怎么选型?

第三部分:面试者参考回答(三步法口语化,300-400 字)

【一句话结论】

面试官您好,万人在线的核心是"状态存 Redis + 广播走 Pub/Sub + 长连接走 WebSocket",麦位管理用 SETNX + Lua 保证原子性,在线人数用心跳保活 + 超时清理。

【三点展开】

第一,架构分层:WebSocket 网关(Netty)负责用户长连接,无状态化便于横向扩展;房间状态服务负责业务逻辑,状态全部存 Redis(在线人数 INCR/DECR、麦位 SET、排队 LIST);Redis Pub/Sub 负责跨服务器广播状态变更——用户连在 WS 网关 A,状态变更发生在服务器 B,B 发消息到 Pub/Sub,A 订阅后推送给本地连接。

第二,麦位管理有并发陷阱:多用户同时申请同一麦位,用 SETNX mic:{micId} userId 原子占位,失败则进排队队列(LIST);空位时 BLPOP 阻塞等待下一个申请;用户下线/心跳超时触发释放,释放后通知排队用户。Lua 脚本保证"检查麦位空 + 占位"的原子性,避免竞态。

第三,在线人数用心跳保活:客户端 30s 心跳,服务器 60s 超时清理(EXPIRE 自动过期,避免死连接);新用户进房直接读 Redis 拿当前状态,之后通过 WebSocket 订阅房间状态变更,秒级感知。不能用客户端轮询——万人 QPS 会打爆服务器。强一致(麦位状态同步广播,延迟 < 100ms)和最终一致(聊天消息走 MQ,秒级收敛)按场景选型。

【一句边界】

当然,如果是百万级并发(YY 语音、KOOK),自建成本高,直接用 IM 云(融云/环信/腾讯云 IM)+ WebSocket 自建弹幕系统更划算——核心是"麦位状态自建,聊天消息用云"。