![图片[1] - 钉钉亿级IM架构设计揭秘:八大核心原则与落地实践 - 宋马](https://pic.songma.com/blogimg/20251113/c3066cb4c8d84ae19890193966fde317.png)
架构图链接:https://www.processon.com/preview/6909ad7bfe712334c9c86581
前言:为什么钉钉IM能支撑亿级并发?
作为日活过亿的企业级应用,钉钉的即时通讯系统面临着极其复杂的挑战:海量消息、高并发、多租户隔离、业务快速迭代… 在这背后,是一套经过千锤百炼的架构设计哲学。
今天,我将揭秘钉钉IM的八大核心设计原则,这些原则不仅适用于IM系统,对任何高并发、多租户的SaaS系统都具有重要参考价值。
一、Identity-First设计:一切从身份出发
核心设计
-- 全局唯一ID格式:uid@tenant_id@idp_type
-- 示例:123456@alibaba-inc.com@dingtalk
落地实践
URL设计:日志格式:在所有业务日志中先输出身份信息,再输出业务内容JWT预埋:Day-0就在JWT中预埋idp_type字段,为后续多身份源扩展做准备
/v1/messages/{tenant_id}/{user_id}
核心价值
# 审计时直接grep特定租户
grep "alibaba-inc.com" app.log | grep "send_message"
# 跨云、跨合并场景下永不重号
# 即使两个公司合并,ID天然隔离
二、「IM-Core + Biz-Skin」两层架构
架构分层
┌─────────────────────────────────────────┐
│ Biz-Skin Layer │
│ 审批 │ 日历 │ 打卡 │ 项目 │ 客户管理 │
└─────────────────────────────────────────┘
│ 订阅事件
┌─────────────────────────────────────────┐
│ IM-Core Layer │
│ 消息 │ 通道 │ 序列表 │
└─────────────────────────────────────────┘
关键约束
-- Core层独立schema,业务层只能订阅,不能直接修改
CREATE SCHEMA im_core; -- 万年不动的核心
CREATE SCHEMA biz_skin; -- 快速变化的业务
多租户适配
同一套IM引擎,通过不同的Biz-Skin实现:
班级群:作业通知、成绩发布客户群:商机跟进、客户服务政府钉:公文流转、政务通知
三、多级缓存:体验护城河
缓存层级设计
客户端内存缓存(L1) → Redis集群缓存(L2) → 本地内存缓存(L3)
↓ ↓ ↓
<5k群成员 at列表 Guava缓存
全量缓存 群卡片 30s过期
性能表现
// 万人群拉取成员列表仍<200ms
@Cacheable(value = "groupMembers", key = "#groupId")
public List<Member> getGroupMembers(Long groupId) {
// L1: 客户端缓存 → L2: Redis → L3: Local Cache → DB
}
落地三板斧
Cache-Aside模式:先读缓存,不存在再读DBRedis集群:分布式缓存,保障高可用客户端增量diff:只同步变化数据,减少传输量
四、冷热分离 + 单元化:成本与稳定性双赢
存储架构
-- 热数据:近7天消息,SSD存储
CREATE TABLE messages_hot (
id BIGINT,
tenant_id INT,
content TEXT,
created_time DATETIME
) PARTITION BY RANGE (TO_DAYS(created_time));
-- 冷数据:历史消息,高压缩存储
CREATE TABLE messages_cold (
id BIGINT,
tenant_id INT,
content MEDIUMBLOB, -- ZSTD压缩
created_time DATETIME
) PARTITION BY HASH(tenant_id) PARTITIONS 64;
单元化设计
// 按租户分片,单单元故障只影响1/64租户
public class TenantSharding {
public int calculateShard(String tenantId) {
return Math.abs(tenantId.hashCode()) % 64;
}
}
归档策略
-- 按月归档,直接drop分区
ALTER TABLE messages_hot
DROP PARTITION p202312;
五、Feature-Flag > Code-Branch:灰度发布的艺术
功能开关表设计
CREATE TABLE perm_tenant_feature (
id BIGINT,
tenant_id VARCHAR(64),
feature_code VARCHAR(32), -- 'im_read_receipt', 'check_in'
status ENUM('on', 'off', 'gray'),
updated_time DATETIME
);
配置中心管理
# 不是在代码中写死,而是在配置中心动态管理
features:
im_read_receipt:
default: off
gray_tenants: ["alibaba-inc.com", "antgroup.com"]
check_in:
default: off
紧急回滚
-- 1条SQL完成全平台回滚
UPDATE perm_tenant_feature
SET status = 'off'
WHERE feature_code = 'new_ui_feature';
六、安全左移 + 零信任通道
全链路加密
// TLS 1.3 + 国密SM4可选
public class EncryptionConfig {
@Value("${encryption.type:tls1.3}")
private String encryptionType;
@Value("${encryption.sm4.enabled:false}")
private boolean sm4Enabled;
}
租户密钥独立
// 每个租户独立的密钥管理
public class TenantKeyService {
public String getTenantKey(String tenantId) {
return KMS.getKey("tenant/" + tenantId);
}
}
极限压测
# CI中每晚自动执行的压测脚本
pressure_test:
scenarios:
- name: 4k_video_group
users: 10000
duration: 1h
- name: large_group_spam
users: 50000
duration: 2h
七、PaaS优先,SaaS其次:生态化战略
核心边界
钉钉基座(永不动) → 生态应用(无限扩展)
↓ ↓
IM + 通讯录 + 文档 审批、打卡、项目...
小程序运行时架构
// 基座只提供SDK和身份事件
public class DingTalkMiniProgramRuntime {
public void registerApp(String appId, Feature[] features) {
// 动态加载第三方应用
}
}
事件总线集成
// 第三方应用通过事件总线接入
@EventListener
public void handleMessageEvent(MessageEvent event) {
// 审批应用监听消息事件
approvalService.onNewMessage(event);
}
八、落地实施清单:从Day-0到Month-3
| 钉钉理念 | 你的落地动作 | 时间点 | 关键产出 |
|---|---|---|---|
| Identity-First | JWT含tenant+idp+region | Day-0 | 统一身份体系 |
| IM-Core独立 | message表禁止业务外键 | Day-0 | 核心稳定性 |
| 多级缓存 | 群成员Redis+客户端缓存 | Day-7 | <200ms响应 |
| 冷热分离 | 消息按时间分区,>30天迁冷 | Month-1 | 存储成本降60% |
| Feature-Flag | perm_tenant_feature表+配置中心 | Day-0 | 灰度发布能力 |
| 单元化 | tenant_id HASH 64子分区 | Month-2 | 故障隔离能力 |
| PaaS化 | 提供小程序runtime & 事件总线 | Month-3 | 生态扩展基础 |
总结:架构设计的长期价值
钉钉IM架构的成功不在于使用了多少新技术,而在于对核心原则的坚守和持续演进的能力。这些设计原则经历了从千万到亿级用户的考验,证明了其在复杂企业级场景下的生命力。
最重要的三个启示:
身份先行:良好的身份设计是扩展性的基础核心稳定:Core层要像”万年基石”一样稳定渐进式演进:通过Feature-Flag实现平滑升级
希望这些经验能帮助你在自己的架构设计中,少走弯路,构建出更加稳定、可扩展的系统。
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END












暂无评论内容