即时通讯(1)-系统架构


一、项目目录

1、基础模块:用户、关系链、群组

2、Netty实现 TCP 网关,同时支持 WebSocket

3、基础模块联动 TCP 服务,实现多端同步和业务回调

4、单聊、群聊核心消息的收发

5、消息实时性、有序性、一致性优化

6、揭秘 QQ 、微信数据同步的优化及客户端数据库 Sqlite

7、在线状态功能开发

8、介绍 IM 扩展功能如何实现

9、演示项目如何接入即时通讯系统

二、即时通讯系统架构

image-20230518171435119

  • 接入层:保持长连接、协议解析、session维护、消息推送
  • 逻辑层:业务模块

三、关系链

1、弱好友关系(微博)

弱好友关系即只存在关注与被关注的关系,可单方面的关注,如微博

表设计需要维护两张表,关注表,被关注表(粉丝表)

关注表字段:

  • 用户id
  • 该用户关注的用户id
  • 类型:关注、拉黑

粉丝表字段:

  • 用户id
  • 关注该用户的粉丝id
  • 类型:关注、拉黑

image-20230524103250298

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自定义路由规则)


  目录