微服务架构IM聊天系统
Github:[项目网址(github.com)](https://github.com/linzhiyouyu/Microservices-Based-Instant-Messaging-System)
安装需要的库及Docker
chmod +x ./install_packs.sh
./install_packs.sh
不直接使用原生spdlog,而是进行二次封装
- 避免单例的锁冲突,因此直接创建全局的线程安全日志器进行使用
- 因为日志输出没有行号和文件名,使用宏进行二次封装来输出行号和文件名
- 封装初始化接口,对于调试模式输出到stdout中,否则输出到文件中
服务注册中心
使用etcd
键值存储系统
- 服务注册:服务启动时,向
etcd
注册自己的地址和端口。 - 服务发现:客户端通过
etcd
获取服务的地址和端口,用于远程调用。 - 健康检查:服务定期向
etcd
发送心跳,以维持其注册信息的有效性。
对etcd-client-api
进行二次封装,实现两种类型的客户端
- 服务注册客户端:向
etcd
注册并保活 - 服务发现客户端:从服务端查找数据,并进行改变事件监控
使用brpc
远程调用框架
使用brpc
远程调用框架,将本地数据处理的过程交给服务器来处理,利用服务端更强的算力来解决问题。
etcd
与brpc
整合
brpc
针对特定的请求来向服务端进行rpc
调用从而构建响应,但是具体向哪台服务器请求需要由etcd
实现的注册中心来进行配合。
更具体地,通过etcd
注册中心就够获知,"谁"能提供"什么"服务,进行能够连接它,从而发起服务调用。由于不同的服务有不同的调用接口,功能也不一样,所以无法对具体的调用进行封装,所以这里的思想就是管理channel
通信信道(将不同主机节点的通信信道管理起来,如果有多个节点能够提供相同的服务,采用RR
轮转来进行负载均衡)。
初步架构:
服务注册端
- 构造
Echo
服务 - 搭建
RPC
服务器 - 运行
RPC
服务 - 向
etcd
注册中心注册本RPC
节点提供的服务
服务发现端 - 构造
RCP
信道管理对象 - 构造服务发现对象
- 通过
RPC
信道管理对象,获取提供Echo
服务信道 - 发起
RPC
调用
关键词搜索子服务
使用elasticsearch
来进行搜索
使用场景:
- 添加好友时关键字搜索
- 查询历史聊天消息时关键字搜索
关于httplib
与websocketpp
的选择,一开始是想只用后者,因为既支持http
又支持websocket
比较方便。
但是后来在实际并发测试的时候不知道为什么websocketpp
总是会漏掉一些请求或者一些意料之外的异常。
处于稳定性考虑,http
协议通信采用httplib
。
redis
使用场景:
- 短信验证码过期设置
- 用户再次登录身份认证
- 群聊
odb
使用odb
来构建对象关系映射,将数据结构与数据库表进行映射,通过对数据结构的操作即可完成对表的curd
微服务架构:
-
网关子服务
与客户端直接交互,用于接收客户端不同类型的请求。经过用户鉴权之后将不同的请求分发到各个子服务进行处理,接收到响应后返回给客户端。
用户鉴权:客户端在登录成功后,后台为客户端创建登录会话并向客户端返回一个登录会话ID。往后客户端发起的请求需要携带ID,否则视为未登录。非登录状态下不允许提供除注册/登录/验证码获取之外的所有服务。 -
消息转发子服务
- 对消息进行组织发送给网关。
- 网关通过消息转发子服务来获取到该用户当前会话中有哪些成员,获取到成员之后组织好基本信息再告知网关,由网关来进行回复。
- 离线用户收不到消息,所以将消息交给RabbitMQ进行"持久化"。