记录一下最近对im功能的设计
写扩散
- 1)遍历群聊的成员并发送消息;
- 2)群聊所有人都存一份;
- 3)查询每个成员的在线状态;
- 4)在线的实时推送。
读扩散
- 1)遍历群聊的成员并发送消息;
- 2)先存一份消息实体;
- 3)然后群聊所有人都存一份消息实体的 ID 引用;
- 4)查询每个成员的在线状态;
- 5)在线的实时推送。
- 用户
- 用户->用户终端设备:每个用户能够多端登录并收发消息;
- 用户->消息:考虑到读扩散,每个用户与消息的关系都是 1:n;
- 用户->消息队列:考虑到读扩散,每个用户都会维护自己的一份“消息列表”(1:1),如果考虑到扩容,甚至可以开辟一份消息溢出列表接收超出“消息列表”容量的消息数据(此时是 1:n);
- 用户->用户连接状态:考虑到用户能够多端登录,那么 app/web 都会有对应的在线状态信息(1:n);
- 用户->联系人关系:考虑到用户最终以某种业务联系到一起,组成多份联系人关系,最终形成私聊或者群聊(1:n);
- 联系人关系
- 业务决定用户与用户之间的关系:比如说,某个家庭下有多少人,这个家庭群聊就有多少人;在 ToB 场景,在钉钉企业版里,我们往往有企业群聊这个存在;
- 消息
- 消息->消息队列:考虑到读扩散,消息最终归属于一个或多个消息队列里,因此群聊场景它会分布在不同的消息队列里;
- 消息队列
- 消息队列:确切说是消息引用队列,它里面的索引元素最终指向具体的消息实体对象
- 用户连接状态
- 用户连接状态:
- 对于 app 端:网络原因导致断线,或者用户手动 kill 掉应用进程,都属于离线
- 对于 web 端:网络原因导致浏览器断网,或者用户手动关闭标签页,都属于离线
- 对于公众号:无法分别离线在线
- 对于小程序:无法分别离线在线
- 用户终端设备
- 终端设备:客户端一般是 Android&IOS,web 端一般是浏览器,还有其他灵活的 WebView(公众号/小程序)
Reference
《基于实践,设计一个百万级别的高可用 & 高可靠的 IM 消息系统》-腾讯云开发者社区-腾讯云 (tencent.com)