Files
interview/questions/design-im.md
yasinshaw 71e3497bfd feat: add comprehensive system design interview questions
- design-seckill.md: 秒杀系统设计
- design-shorturl.md: 短链接系统设计
- design-lbs.md: LBS附近的人系统设计
- design-im.md: 即时通讯系统设计
- design-feed.md: 社交信息流系统设计

Each document includes:
- Requirements analysis and data volume assessment
- Technical challenges
- System architecture design
- Database design
- Caching strategies
- Scalability considerations
- Practical project experience
- Alibaba P7 level additional points

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 23:43:36 +08:00

424 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 即时通讯系统设计
## 需求分析和数据量评估
### 需求分析
- **核心功能**:单聊、群聊、消息推送、在线状态
- **业务场景**:社交应用、企业通讯、客服系统
- **QPS评估**日消息100亿+峰值QPS 10万+
- **数据规模**用户1亿+好友关系10亿+历史消息1000亿+
### 数据量评估
- **用户表**1亿条日均查询1000万次
- **好友关系表**10亿条日均更新100万次
- **消息表**1000亿+条日增1亿+
- **群组表**1亿+条日均查询100万次
- **离线消息**100亿+条日均推送1亿+
## 核心技术难点
### 1. 高并发消息处理
- 亿级用户同时在线
- 消息的实时性要求
- 消息的可靠性保证
### 2. 消息存储优化
- 海量消息数据存储
- 消息的快速检索
- 历史消息清理
### 3. 在线状态管理
- 实时在线状态同步
- 心跳检测机制
- 离线状态管理
### 4. 消息推送优化
- 推送延迟控制
- 消息去重
- 推送失败重试
## 系统架构设计
### 总体架构
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 移动端APP │ │ PC客户端 │ │ Web网页 │
│ (iOS/Android)│ │ (Windows) │ │ (Web) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 负载均衡 │ │ API网关 │ │ CDN加速 │
│ (Nginx) │ │ (Gateway) │ │ (Edge) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 网关服务 │ │ 业务服务 │ │ 推送服务 │
│ (Gateway) │ │ (微服务) │ │ (Service) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└─────────────────────┼───────────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 消息队列 │ │ Redis集群 │ │ 数据库集群 │
│ (Kafka/Pulsar)│ │ (缓存+pub/sub)│ │ (MySQL分库分表)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 消息存储 │ │ 文件存储 │ │ 搜索引擎 │
│ (MongoDB) │ │ (MinIO/S3) │ │ (Elasticsearch)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 关键组件
#### 1. 流量层
- **负载均衡**Nginx L7负载均衡
- **API网关**:请求路由、限流、认证
- **CDN加速**:静态资源缓存
#### 2. 服务层
- **网关服务**:连接管理、协议转换
- **业务服务**:消息处理、关系管理
- **推送服务**:消息推送、状态同步
- **通知服务**:系统通知、消息提醒
#### 3. 存储层
- **Redis集群**:在线状态、会话管理
- **MySQL集群**:用户数据、关系数据
- **MongoDB集群**:消息存储、历史记录
- **消息队列**:异步处理、削峰填谷
#### 4. 基础设施
- **消息存储**:分布式文件系统
- **搜索引擎**:消息全文检索
- **监控系统**:实时监控告警
- **日志系统**:业务日志记录
## 数据库设计
### 用户表
```sql
CREATE TABLE `im_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`username` varchar(50) NOT NULL COMMENT '用户名',
`nickname` varchar(50) NOT NULL COMMENT '昵称',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`gender` tinyint DEFAULT 0 COMMENT '性别',
`birthday` date DEFAULT NULL COMMENT '生日',
`signature` varchar(255) DEFAULT NULL COMMENT '个性签名',
`mobile` varchar(20) DEFAULT NULL COMMENT '手机号',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`last_login` timestamp DEFAULT NULL COMMENT '最后登录时间',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 好友关系表
```sql
CREATE TABLE `im_friends` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`friend_id` bigint NOT NULL COMMENT '好友ID',
`remark` varchar(50) DEFAULT NULL COMMENT '备注',
`group_name` varchar(50) DEFAULT NULL COMMENT '分组名',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_friend` (`user_id`, `friend_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_friend_id` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 消息表
```sql
CREATE TABLE `im_message` (
`id` bigint NOT NULL AUTO_INCREMENT,
`message_id` varchar(64) NOT NULL COMMENT '消息ID',
`from_user_id` bigint NOT NULL COMMENT '发送者ID',
`to_user_id` bigint DEFAULT NULL COMMENT '接收者ID',
`group_id` bigint DEFAULT NULL COMMENT '群组ID',
`message_type` tinyint NOT NULL COMMENT '消息类型',
`content` text COMMENT '消息内容',
`is_read` tinyint NOT NULL DEFAULT 0 COMMENT '是否已读',
`is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否已删除',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_message_id` (`message_id`),
KEY `idx_from_user` (`from_user_id`),
KEY `idx_to_user` (`to_user_id`),
KEY `idx_group_id` (`group_id`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 群组表
```sql
CREATE TABLE `im_group` (
`id` bigint NOT NULL AUTO_INCREMENT,
`group_id` bigint NOT NULL COMMENT '群组ID',
`group_name` varchar(100) NOT NULL COMMENT '群名称',
`avatar` varchar(255) DEFAULT NULL COMMENT '群头像',
`creator_id` bigint NOT NULL COMMENT '创建者ID',
`member_count` int NOT NULL DEFAULT 0 COMMENT '成员数',
`max_members` int DEFAULT 500 COMMENT '最大成员数',
`description` text COMMENT '群描述',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 群组成员表
```sql
CREATE TABLE `im_group_member` (
`id` bigint NOT NULL AUTO_INCREMENT,
`group_id` bigint NOT NULL COMMENT '群组ID',
`user_id` bigint NOT NULL COMMENT '用户ID',
`role` tinyint NOT NULL DEFAULT 0 COMMENT '角色',
`nickname` varchar(50) DEFAULT NULL COMMENT '群昵称',
`join_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_user` (`group_id`, `user_id`),
KEY `idx_group_id` (`group_id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
## 缓存策略
### Redis缓存设计
```typescript
// 用户在线状态
const ONLINE_STATUS_PREFIX = 'online:';
const ONLINE_STATUS_TTL = 300; // 5分钟
// 会话信息
const SESSION_PREFIX = 'session:';
const SESSION_TTL = 3600; // 1小时
// 未读消息计数
const UNREAD_PREFIX = 'unread:';
const UNREAD_TTL = 86400; // 24小时
// 消息已读状态
const READ_PREFIX = 'read:';
const READ_TTL = 604800; // 7天
// 最近会话
const RECENT_SESSION_PREFIX = 'recent:';
const RECENT_SESSION_TTL = 86400; // 24小时
```
### 缓存策略
1. **多级缓存**
- 本地缓存Caffeine
- 分布式缓存Redis Cluster
- 内存缓存:热点数据缓存
2. **缓存更新策略**
- Write Through写入同时更新缓存
- Write Behind异步更新缓存
- Cache Invalidation定时失效
3. **消息缓存**
- 最近消息缓存
- 群组信息缓存
- 用户状态缓存
### WebSocket实现
```java
public class WebSocketHandler extends TextWebSocketHandler {
private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 用户上线
String userId = getUserIdFromSession(session);
sessions.put(userId, session);
// 更新在线状态
redisTemplate.opsForValue().set(ONLINE_STATUS_PREFIX + userId, "1", ONLINE_STATUS_TTL);
// 通知好友用户上线
notifyFriendsOnline(userId);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String userId = getUserIdFromSession(session);
Message msg = parseMessage(message.getPayload());
// 处理消息
handleMessage(userId, msg);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// 用户下线
String userId = getUserIdFromSession(session);
sessions.remove(userId);
// 更新在线状态
redisTemplate.delete(ONLINE_STATUS_PREFIX + userId);
// 通知好友用户下线
notifyFriendsOffline(userId);
}
private void handleMessage(String fromUserId, Message msg) {
switch (msg.getType()) {
case SINGLE_CHAT:
sendSingleMessage(fromUserId, msg);
break;
case GROUP_CHAT:
sendGroupMessage(fromUserId, msg);
break;
case TYPING:
sendTypingMessage(fromUserId, msg);
break;
}
}
private void sendSingleMessage(String fromUserId, Message msg) {
String toUserId = msg.getToUserId();
WebSocketSession session = sessions.get(toUserId);
if (session != null && session.isOpen()) {
// 用户在线,直接推送
session.sendMessage(new TextMessage(msg.toJson()));
} else {
// 用户离线,存储离线消息
saveOfflineMessage(fromUserId, toUserId, msg);
}
// 更新未读消息计数
updateUnreadCount(fromUserId, toUserId);
}
}
```
## 扩展性考虑
### 1. 水平扩展
- **无状态服务**:业务服务无状态化
- **数据分片**按用户ID分片
- **读写分离**:主库写入,从库读取
### 2. 垂直扩展
- **服务拆分**:网关服务、业务服务、推送服务
- **数据分层**:热数据、温数据、冷数据
- **多级缓存**本地、Redis、CDN
### 3. 消息可靠性
- **消息持久化**:消息队列持久化
- **重试机制**:消息发送失败重试
- **消息去重**ID去重机制
### 4. 容灾备份
- **多活架构**:多机房部署
- **故障转移**:自动故障检测和转移
- **数据备份**:定时备份和实时同步
## 实际项目经验
### 1. 技术栈选择
- **前端**React Native + Flutter
- **后端**Spring Boot + Node.js
- **数据库**MySQL + MongoDB + Redis
- **消息队列**Kafka + Pulsar
- **通信协议**WebSocket + MQTT
### 2. 性能优化
- **消息压缩**Gzip压缩消息内容
- **批量处理**:批量消息处理
- **连接池**:数据库连接池优化
- **缓存优化**:多级缓存策略
### 3. 运维部署
- **容器化**Docker + Kubernetes
- **CI/CD**Jenkins + GitLab
- **监控告警**ELK Stack + AlertManager
- **压测**JMeter + Locust
### 4. 安全设计
- **消息加密**:端到端加密
- **身份认证**JWT Token认证
- **消息防刷**:频率限制
- **数据脱敏**:敏感信息过滤
## 阿里P7加分项
### 1. 架构设计能力
- **高可用架构**99.99%可用性
- **高性能架构**:支持亿级消息
- **扩展性架构**:弹性扩缩容
### 2. 技术深度
- **分布式系统**:分布式缓存、分布式消息
- **通信协议**WebSocket、MQTT协议
- **实时系统**:实时消息处理
### 3. 业务理解
- **社交业务**:理解社交应用场景
- **企业通讯**:掌握企业通讯需求
- **用户行为**:分析消息使用模式
### 4. 团队管理
- **技术团队**带领30人+团队
- **项目管控**:管理亿级用户项目
- **技术方案**:主导架构设计
### 5. 前沿技术
- **AI应用**:智能回复、消息分类
- **边缘计算**:边缘节点处理
- **Serverless**:函数化服务
## 面试常见问题
### 1. 如何保证消息不丢失?
- **持久化存储**:消息队列持久化
- **重试机制**:失败消息重试
- **确认机制**消息确认ACK
- **补偿机制**:定时补偿任务
### 2. 如何处理海量消息存储?
- **分库分表**:按时间分片
- **数据归档**:冷热数据分离
- **压缩存储**:消息内容压缩
- **生命周期管理**:自动清理过期数据
### 3. 如何实现消息实时性?
- **长连接**WebSocket长连接
- **推送机制**:实时推送
- **心跳检测**:连接保持
- **故障转移**:自动重连
### 4. 如何处理消息去重?
- **消息ID**全局唯一ID
- **幂等设计**:处理重复消息
- **去重表**:已处理消息记录
- **时间窗口**:时间窗口去重
### 5. 如何优化消息推送性能?
- **批量推送**:批量消息推送
- **连接池**:连接复用
- **异步处理**非阻塞IO
- **缓存优化**:推送结果缓存