项目git链接 :mq/mqdemo/muduo/protobuf/protobuf_client.cpp · 耀空/项目mq - 码云 - 开源中国
使用技术简介:
开发主语言:C++
序列化框架:Protobuf 二进制序列化
网络通信:自定义应用层协议 + muduo 库(对 tcp 长连接的封装、并且使用 epoll 的事件驱动模式,实现高并发服务器与客户端)
源数据信息数据库: SQLite3
单元测试框架: Gtest
- 首先,我们要知道我们这个项目是如何运行的,然后才能划分不同的模块进行编写;根据上一篇项目设计中我们就可以知道了具体要分为哪几个模块;现在要把他们设计出,还要知道它们的功能有那些,要管理什么资源,模块之间的连续;这样之后就可以在server.hpp直接把他们整合到一起;
- 当然每个模块写完之后都有进行测试,这里使用gtest的功能;所有测试见:mq/mqtest · 耀空/项目mq - 码云 - 开源中国
首先要说的是持久化数据管理中心模块
持久化数据管理中心模块
在数据管理模块中管理交换机,队列,队列绑定,消息等部分数据数据。
流程图:
从这个broker服务器的简单流程图,可以知道持久化是什么东西。
主要就是 在服务器重启后,可以再次获得这些资源;
主要就是使用SQlite3这个功能;
下面的管理都是在 不同的模块中实现的,把数据存储在sqlite数据库中;
这些是在模块完成的最后实现,利用sqlite数据库;
与模块实现的逻辑关系不强;
- 交换机管理:
**管理信息:**名称,类型,是否持久化标志,是否(无人使用时)自动删除标志,其他参数,....
**管理操作:**恢复历史信息,声明,删除,获取,判断是否存在
- 队列管理:
**管理信息:**名称,是否持久化标志,是否独有标志,是否(无人使用时)自动删除标志,其他参数,....
**管理操作:**恢复历史信息,声明,删除,获取,判断是否存在
- 绑定管理:
**管理信息:**交换机名称,队列名称,绑定主题
**管理操作:**恢复历史信息,绑定,解绑,解除交换机关联绑定信息,解除队列关联绑定信息,获取交换机关联绑定信息
- 消息管理:
**管理信息:**属性:消息ID, 路由主题,持久化模式标志 ,消息内容,有效标志(持久化需要),持久化位置(内存中),持久化消息长度(内存中)
**管理操作:**恢复历史信息,向指定队列新增消息,获取指定队列队首消息,确认移除消息
注意:
这几个核心概念数据都需要在内存和硬盘中存储的。
- 以内存存储为主,主要是保证快速查找信息进行处理
- 以硬盘存储为辅,主要是保证服务器重启之后,之前的信息都可以正常保持
这里的硬盘储存其实就是,数据库也就是文件夹,
代码见:
以上模块的文件中,******Mapper类的实现,就是各模块的持久化的实现
mq/mqsever · 耀空/项目mq - 码云 - 开源中国
https://gitee.com/yaokong123/project-mq/tree/master/mq/mqsever
交换机模块
认识
当客户端发布一条消息到交换机后,这条消息,应该被入队到该交换机绑定的哪些队列中?交换路由模块就是决定这件事情的。
在绑定信息中有一个binding_key,而每条发布的消息中有一个routing_key,能否入队取决于两个要素:交换机类型和key
而且要三种广播类型已经说过,所以这里要管理的数据就已经知道了
流程图
从这个broker服务器的简单流程图,可以知道交换机类 因该怎么写;
交换机数据管理
- 要管理的数据:描述了一个交换机应该有什么数据
- 交换机名称:唯一标识
- 交换机类型:决定了消息的转发方式每个队列绑定中有个 binding_key, 每条消息中有个 routing_key
- 直接交换: binding_key 与 routing_key 相同,则将消息放入队列
- 广播交换:将消息放入交换机绑定的所有队列中
- 主题交换: routing_key 与多个绑定队列的 binding_key 有个匹配规则,匹配成功了则放入
- 持久化标志:决定了当前交换机信息是否需要持久化存储
- 自动删除标志:就是关联了当前交换机的所有客户端都退出了,是否要自动删除交换机 (其实这里没有实现)
- 交换机的其他参数:这个项目里未使用。
对交换机的管理操作
- 创建交换机:本质上需要的是声明 ------ 强断言的思想 - 有就 OK,没有则创建的意思
- 删除交换机:注意事项 -- 每个交换机都会绑定一个或多个队列(意味着会有一个或多个绑定信息),因此删除交换机需要删除相关绑定信息
- 获取指定名称交换机。
- 获取当前交换机数量
代码见
交换机模块类
https://gitee.com/yaokong123/project-mq/blob/master/mq/mqsever/mq_exchange.hpp
队列模块
当前队列数据的管理,本质上是队列描述信息的管理,描述当前服务器上有哪些队列。
流程图:
从这个broker服务器的简单流程图,可以知道消息信息类因该怎么写;
要管理的数据
- 队列名称:唯一的标识
- 持久化存储标志:决定了是否将队列信息持久化存储起来,决定了重启后,这个队列还是否存在
- 是否独占标志:独占就指的是,只有当前客户端自己能够订阅队列消息
- 自动删除标志:当订阅了当前队列的所有客户端退出后,是否删除队列(暂未实现)。
- 其他参数:
提供的管理操作
还就是增删查三个操作
- 创建队列
- 删除队列
- 获取指定队列信息
- 获取队列数量
- 获取所有队列名称:当系统重启后,需要重新加载数据,加载历史消息(消息以队列为单元存储在文件中),而加载消息需要知道队列名称,因为后边消息存储的时候,存储文件以队列名称进行的取名
注意:
一个队列如果持久化标志为 false,则意味着重启后,队列就没了,也没有客户端能够订阅队列的消息,因此这个队列的消息如果持久化存储了,是没有意义,因此通常一个队列的持久化标志是 false,那么它的消息也就不需要持久化。
代码见
绑定信息(交换机-队列)管理
绑定数据管理模块:就是描述一下将哪个队列与哪个交换机绑定到了一起
key是怎么组成的
binding_key是怎么组成的?
是由数字字母下划线构成的, 并且使用 . 分成若干部分。
例如:news.music.#,这用于表示交换机绑定的当前队列是一个用于发布音乐新闻的队列
- 支持 * 和 # 两种通配符, 但是 * # 只能作为 . 切分出来的独立部分, 不能和其他数字字母混用,(比如 a.*.b 是合法的, a.*a.b 是不合法的)
- * 可以匹配任意一个单词(注意是单词不是字母)
可以匹配任意零个或者多个单词(注意是单词不是字母)
routing_key
是由数据、字母和下划线构成, 并且可以使用 . 划分成若干部分。
他的组成的准确的;
例如:news.music.pop,这用于表示当前发布的消息是一个流行音乐的新闻.
流程图:
从这个broker服务器的简单流程图,大概可以知道绑定信息类因该怎么写;
管理的数据
- 交换机名称
- 队列名称
- binding_key:绑定密钥 -- 描述了在交换机的主题交换 & 直接交换的消息发布匹配规则
由数字,字符,_、#、.、* 组成:
binding_key: news.music.#
消息中的 routing_key: news.sport.football
具体规则看key是怎么组成的
管理的操作
- 添加绑定
- 解除绑定
- 获取交换机相关的所有绑定信息:
- 删除交换机的时候,要删除相关绑定信息; 2. 当消息发布到交换机,交换机得通过这些信息来将消息发布到指定队列
- 获取队列相关的所有绑定信息:
- 删除队列的时候,要删除相关的绑定信息
- 获取绑定信息数量(纯粹为了测试而添加)

