Organized 50 interview questions into 12 categories: - 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc. - 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理 - 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc. - 04-消息队列 (1 file): RocketMQ/Kafka - 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc. - 06-JVM (1 file): JVM和垃圾回收 - 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc. - 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮 - 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化 - 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx - 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性 - 12-面试技巧 (1 file): 面试技巧和职业规划 All files renamed to Chinese for better accessibility and organized into categorized folders for easier navigation. Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
16 KiB
16 KiB
即时通讯系统设计
需求分析和数据量评估
需求分析
- 核心功能:单聊、群聊、消息推送、在线状态
- 业务场景:社交应用、企业通讯、客服系统
- 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. 基础设施
- 消息存储:分布式文件系统
- 搜索引擎:消息全文检索
- 监控系统:实时监控告警
- 日志系统:业务日志记录
数据库设计
用户表
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;
好友关系表
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;
消息表
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;
群组表
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;
群组成员表
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缓存设计
// 用户在线状态
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小时
缓存策略
-
多级缓存:
- 本地缓存:Caffeine
- 分布式缓存:Redis Cluster
- 内存缓存:热点数据缓存
-
缓存更新策略:
- Write Through:写入同时更新缓存
- Write Behind:异步更新缓存
- Cache Invalidation:定时失效
-
消息缓存:
- 最近消息缓存
- 群组信息缓存
- 用户状态缓存
WebSocket实现
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
- 缓存优化:推送结果缓存