微服务架构IM聊天系统

Github:[项目网址(github.com)](https://github.com/linzhiyouyu/Microservices-Based-Instant-Messaging-System)
安装需要的库及Docker

chmod +x ./install_packs.sh
./install_packs.sh

不直接使用原生spdlog,而是进行二次封装

  1. 避免单例的锁冲突,因此直接创建全局的线程安全日志器进行使用
  2. 因为日志输出没有行号和文件名,使用宏进行二次封装来输出行号和文件名
  3. 封装初始化接口,对于调试模式输出到stdout中,否则输出到文件中

服务注册中心

使用etcd键值存储系统

  1. 服务注册:服务启动时,向etcd注册自己的地址和端口。
  2. 服务发现:客户端通过etcd获取服务的地址和端口,用于远程调用。
  3. 健康检查:服务定期向etcd发送心跳,以维持其注册信息的有效性。

etcd-client-api进行二次封装,实现两种类型的客户端

  1. 服务注册客户端:向etcd注册并保活
  2. 服务发现客户端:从服务端查找数据,并进行改变事件监控

使用brpc远程调用框架

使用brpc远程调用框架,将本地数据处理的过程交给服务器来处理,利用服务端更强的算力来解决问题。

etcdbrpc整合

brpc针对特定的请求来向服务端进行rpc调用从而构建响应,但是具体向哪台服务器请求需要由etcd实现的注册中心来进行配合。
更具体地,通过etcd注册中心就够获知,"谁"能提供"什么"服务,进行能够连接它,从而发起服务调用。由于不同的服务有不同的调用接口,功能也不一样,所以无法对具体的调用进行封装,所以这里的思想就是管理channel通信信道(将不同主机节点的通信信道管理起来,如果有多个节点能够提供相同的服务,采用RR轮转来进行负载均衡)。

初步架构:
服务注册端

  1. 构造Echo服务
  2. 搭建RPC服务器
  3. 运行RPC服务
  4. etcd注册中心注册本RPC节点提供的服务
    服务发现端
  5. 构造RCP信道管理对象
  6. 构造服务发现对象
  7. 通过RPC信道管理对象,获取提供Echo服务信道
  8. 发起RPC调用

关键词搜索子服务

使用elasticsearch来进行搜索
使用场景:

  1. 添加好友时关键字搜索
  2. 查询历史聊天消息时关键字搜索

关于httplibwebsocketpp的选择,一开始是想只用后者,因为既支持http又支持websocket比较方便。
但是后来在实际并发测试的时候不知道为什么websocketpp总是会漏掉一些请求或者一些意料之外的异常。
处于稳定性考虑,http协议通信采用httplib

redis
使用场景:

  1. 短信验证码过期设置
  2. 用户再次登录身份认证
  3. 群聊

odb
使用odb来构建对象关系映射,将数据结构与数据库表进行映射,通过对数据结构的操作即可完成对表的curd

微服务架构:

alt text

  1. 网关子服务
    与客户端直接交互,用于接收客户端不同类型的请求。经过用户鉴权之后将不同的请求分发到各个子服务进行处理,接收到响应后返回给客户端。
    用户鉴权:客户端在登录成功后,后台为客户端创建登录会话并向客户端返回一个登录会话ID。往后客户端发起的请求需要携带ID,否则视为未登录。非登录状态下不允许提供除注册/登录/验证码获取之外的所有服务。

  2. 消息转发子服务
    alt text

  1. 对消息进行组织发送给网关。
  2. 网关通过消息转发子服务来获取到该用户当前会话中有哪些成员,获取到成员之后组织好基本信息再告知网关,由网关来进行回复。
  3. 离线用户收不到消息,所以将消息交给RabbitMQ进行"持久化"。