Files
interview/questions/07-系统设计/即时通讯系统设计.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
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>
2026-03-01 00:10:53 +08:00

16 KiB
Raw Blame History

即时通讯系统设计

需求分析和数据量评估

需求分析

  • 核心功能:单聊、群聊、消息推送、在线状态
  • 业务场景:社交应用、企业通讯、客服系统
  • 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小时

缓存策略

  1. 多级缓存

    • 本地缓存Caffeine
    • 分布式缓存Redis Cluster
    • 内存缓存:热点数据缓存
  2. 缓存更新策略

    • Write Through写入同时更新缓存
    • Write Behind异步更新缓存
    • Cache Invalidation定时失效
  3. 消息缓存

    • 最近消息缓存
    • 群组信息缓存
    • 用户状态缓存

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/CDJenkins + 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
  • 缓存优化:推送结果缓存