O21 · Design a Chat Room O21 · 设计聊天室
Verified source经核实出处
Listed in 小红书 @Infra+RL+Robots recruiter post (2026) as one of OpenAI's 5 SD-pool questions. Distinct from O4 (Design Slack) — a Chat Room has a single logical room with many members, no DMs / workspaces / threads. Credibility B.来自小红书 @Infra+RL+Robots 招聘官(2026)列出的 OpenAI 五大 SD 题池之一。与 O4(Slack)不同——聊天室是单一逻辑房间多成员,不含 DM / 工作区 / Thread。可信度 B。
Scoping: Chat Room ≠ Slack范围:聊天室 ≠ Slack
| Capability | Chat Room (O21) | Slack (O4) |
|---|---|---|
| Room structure | Single room id, broadcast to all joined members.单房间 id,广播给所有加入成员。 | Workspaces → channels → threads → DMs.工作区 → 频道 → Thread → DM。 |
| History | Bounded or session-based; some variants are ephemeral.有界或 session 内;部分变体瞬时。 | Permanent, searchable, paginated.永久保存、可搜索、分页。 |
| Ordering | Per-room monotonic seq.每房间单调递增 seq。 | Per-channel seq.每频道 seq。 |
| Presence | Active member list, typing indicators.在线成员列表、正在输入指示。 | User-global presence (online/away).用户全局在线状态(在线/离开)。 |
Architecture架构
flowchart LR C1[Client A] & C2[Client B] --> LB[WS Load Balancer
sticky by room_id] LB --> WS1[WS Gateway 1] LB --> WS2[WS Gateway 2] WS1 & WS2 --> RC[Room Coordinator
Redis pub/sub] WS1 & WS2 --> MSG[Message Service] MSG --> DB[(Messages: room_id, seq, payload)] MSG --> SEQ[Seq Generator
Redis INCR per room] WS1 --> PRES[Presence Service
Redis TTL]
Message flow (hot path)消息流(热路径)
- Client sends over existing WS:
{type:"msg", room_id, client_msg_id, text}.客户端通过已有 WS 发送{type:"msg", room_id, client_msg_id, text}。 - Gateway dedups on
client_msg_id, calls Message Service.网关按client_msg_id去重,调用 Message Service。 - Message Service assigns
seq = INCR room:{id}:seq, persists, then publishes toroom:{id}channel.Message Service 通过INCR room:{id}:seq分配 seq,持久化后发布到room:{id}频道。 - All WS gateways subscribing to that channel push to local clients.所有订阅该频道的 WS 网关将消息推送到本地客户端。
Connection & room state连接与房间状态
- Sticky routing: hash
room_id→ a shard of WS gateways → keeps pub/sub fan-out local.粘性路由:room_id哈希 → 一组 WS 网关 → 保持 pub/sub 本地 fan-out。 - Join/Leave: WS gateway maintains
Map<room_id, Set<conn>>; on join, subscribe to Redis channel; on last-leaver, unsubscribe.加入/离开:WS 网关维护Map<room_id, Set<conn>>;加入时订阅 Redis 频道;最后一人离开时退订。 - Reconnect: client sends
last_seq; server ships missed messages then subscribes stream.重连:客户端带last_seq;服务端补发 + 订阅流。
Follow-ups追问
- 10K-member room fan-out storm? Shard the room across multiple pub/sub channels; or switch to a dedicated "mega-room" service that buffers and batches pushes.1 万人大房间 fan-out 风暴?把房间拆到多个 pub/sub 子频道;或切到专用「超级房间」服务做缓冲批量推送。
- Typing indicators at scale? Not persisted; rate-limited (e.g., 1 "typing" event per 3 s per user); use a separate ephemeral pub/sub topic.大规模正在输入?不持久化;限流(每用户每 3 秒 1 次);用独立的瞬时 pub/sub 主题。
- Moderation? Synchronous blocklist/regex check inline; async classifier after; client can render a "pending-review" placeholder.内容审核?同步 blocklist/正则;异步分类器;客户端渲染「审核中」占位。
- End-to-end encryption? Signal-like; server stores ciphertext + metadata only; but room join needs key rotation on member change.端到端加密?Signal 风格;服务端仅存密文 + 元数据;成员变更时需密钥轮换。