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>
This commit is contained in:
424
questions/design-im.md
Normal file
424
questions/design-im.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# 即时通讯系统设计
|
||||
|
||||
## 需求分析和数据量评估
|
||||
|
||||
### 需求分析
|
||||
- **核心功能**:单聊、群聊、消息推送、在线状态
|
||||
- **业务场景**:社交应用、企业通讯、客服系统
|
||||
- **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
|
||||
- **缓存优化**:推送结果缓存
|
||||
Reference in New Issue
Block a user