System Design: Cloudflare Serverless Chat App
基于 Cloudflare Workers、Durable Objects、KV 和 D1 构建全球无服务器实时聊天应用系统设计。
构建支持全球数百万用户的高并发、低延迟实时聊天应用(Real-time Chat App)是系统设计(System Design)中的经典难题。在 AWS Lambda 等传统 Serverless 架构中,由于函数具有无状态(Stateless)和短生命周期的特点,维持长连接的 WebSocket 非常困难且成本高昂。
利用 Cloudflare Edge Platform(包括 Workers、Durable Objects、Cloudflare KV 和 D1 Database),我们可以构建一个优雅且高性能的 Serverless 聊天系统。
1. 核心挑战:Serverless 架构下的 WebSocket#
传统 Serverless 架构的主要痛点:
- WebSocket 连接状态维持:需要服务端保持长连接。
- 消息路由与广播:如何跨全球边缘节点准确将消息投递给目标房间内的所有用户。
- 低延迟持久化:消息历史记录的高效存储与查询。
2. 整体架构设计 (System Architecture)#
系统包含 4 个核心组件:
- Cloudflare Workers:作为 Edge 网关,处理 HTTP 请求并在靠近用户的边缘节点完成 WebSocket 握手。
- Durable Objects (DO):边缘 Singleton Actor 实例,维护聊天房间的状态与 WebSocket 连接,负责消息广播。
- Cloudflare D1:分布式 SQLite 数据库,持久化存储用户数据和聊天历史。
- Cloudflare KV:超低延迟键值存储,用于 Session 缓存与配置管理。
+--------------+ WebSocket +---------------------+
| User Client | <------------------> | Cloudflare Workers |
+--------------+ +---------------------+
|
Forward / Stub Routing
v
+---------------------+
| Durable Object | (Chat Room State)
| (Room 101 Instance)|
+---------------------+
/ \
v v
+----------------+ +----------------+
| Cloudflare D1 | | Cloudflare KV |
| (Message History)| | (User Session) |
+----------------+ +----------------+text3. 核心代码实现#
3.1. Durable Object: 聊天房间状态协调器#
src/room.ts
export class ChatRoom implements DurableObject {
private state: DurableObjectState;
private sessions: Set<WebSocket> = new Set();
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const pair = new WebSocketPair();
const [client, server] = Object.values(pair);
this.handleSession(server);
return new Response(null, { status: 101, webSocket: client });
}
private handleSession(ws: WebSocket) {
ws.accept();
this.sessions.add(ws);
ws.addEventListener('message', async (msg) => {
try {
const data = JSON.parse(msg.data as string);
// 广播消息给房间内的所有客户端 // [!code focus]
this.broadcast(JSON.stringify({
user: data.user,
text: data.text,
timestamp: new Date().toISOString()
}));
} catch (err) {
ws.send(JSON.stringify({ error: 'Invalid message payload' }));
}
});
ws.addEventListener('close', () => {
this.sessions.delete(ws);
});
}
private broadcast(message: string) {
for (const session of this.sessions) {
session.send(message);
}
}
}typescript4. 架构优势与限制 (Trade-offs)#
[!TIP] 优势:
- 无冷启动:基于 V8 Isolates 在全球边缘节点秒级响应。
- 全球低延迟:用户连接自动调度至最近的 Cloudflare PoP。
[!WARNING] 限制:
- 单个 Durable Object 适合数千连接的房间;若需支持万人超级大群,需引入 DO 树状广播架构 (DO Tree Hierarchy) 进行水平扩展。