一、项目目录
1、基础模块:用户、关系链、群组
2、Netty实现 TCP 网关,同时支持 WebSocket
3、基础模块联动 TCP 服务,实现多端同步和业务回调
4、单聊、群聊核心消息的收发
5、消息实时性、有序性、一致性优化
6、揭秘 QQ 、微信数据同步的优化及客户端数据库 Sqlite
7、在线状态功能开发
8、介绍 IM 扩展功能如何实现
9、演示项目如何接入即时通讯系统
二、即时通讯系统架构
- 接入层:保持长连接、协议解析、session维护、消息推送
- 逻辑层:业务模块
三、关系链
1、弱好友关系(微博)
弱好友关系即只存在关注与被关注的关系,可单方面的关注,如微博
表设计需要维护两张表,关注表,被关注表(粉丝表)
关注表字段:
- 用户id
- 该用户关注的用户id
- 类型:关注、拉黑
粉丝表字段:
- 用户id
- 关注该用户的粉丝id
- 类型:关注、拉黑
2、强好友关系(简单)
强好友关系即微信、QQ这一类型的关系,添加好友后,需要对方同意,才能真正建立好友关系
最简单的表设计方式只需要两个字段,分别标识互为好友的两个用户,如下
- uid1:用户1
- uid2:用户2
查询语句为
select * from friend where uid1 = "zhangsan" union select * from friend uid2 = "zhangsan"
虽然这种设计很简单,但当数据量增大时,系统是无法承受的
3、强好友关系(优化)
针对上述简单版的强好友关系的缺点,我们可以模仿弱好友关系,同过对数据的冗余,来进行优化
即 A 和 B 添加好友,会生成两条记录,一条是 A 处于 fromId,一条是 A 处于 toId
字段名 | 描述 |
---|---|
app_id | 应用id,用于接入的多个应用间的数据隔离 |
from_id | 好友1 |
to_id | 好友2 |
status | 1正常;2删除;3未添加 |
black | 1正常;2拉黑 |
add_source | 添加来源 |
black_sequence | |
friend_sequence |
四、分布式消息推送
分布式系统环境下,需要通讯的两个用户的 Channel
可能存在不同的服务节点中,导致无法直接收发数据。相关的解决方案如下:
- 消息广播
当需要发送消息时,如果接收人不在当前服务节点或是群聊消息,则将该消息发送至所有节点,如果目标节点中有接收人的 Channel
则发送。
优点:实现简单
缺点:会产生消息风暴,如果节点多了,一条消息就得复制发送多份,占用大量资源,所以一般不采用这种方案。
- 一致性哈希
假如有三台服务节点,先对用户的主键(或其他唯一字段)进行哈希并对节点数(3)取模,根据结果确定该用户的 Channel
存放在哪个服务节点上。
当需要发送数据时,对接收人进行哈希并取模,根据结果将消息发送到指定的服务节点上。
优点:计算简单,实现简单
缺点:重度依赖服务发现的稳定性,一定要及时感知到服务是否下线,并且集群水平扩展相对复杂,需要停机
- 构建路由层
使用一个 key-value
的结构来存放用户登录在哪个服务器节点上,当需要发送数据时,先到路由层查找用户在哪个服务节点,根据结果将消息发送到指定的服务节点上。
优点:可水平扩展
缺点:实现复杂,需要引入三方中间件(如 Redis)(Nacos结合Ribbon自定义路由规则)