仿RabbitMQ实现消息队列(六)--项目框架 - 实践


在这里插入图片描述

六、需求分析

6.1核心概念

  • 生产者(Productor)
  • 消费者(Consumer)
  • 中间人(Broker)
  • 发布(Publish)
  • 订阅(Subscribe)
  • 一个生产者,一个消费者
    在这里插入图片描述

N个生产者,N个消费者
在这里插入图片描述

最核心的部分,负责消息的存储和转发。就是其中 Broker Server
而在AMPQ(Advanced Message Queuing Protocol-高级消息队列协议,一个提供统一消息服务的应用层标准高级消息队列协议,为面向消费者的中间件设计,使得遵从该规范的客户端应用和消息中间件服务器的全功能互操作成为可能)模型中

  • 虚拟机(VirtualHost):类似于MySQL的”database“,是一个逻辑上的集合。一个BrokerServer上可以存在多个VirtualHost.
  • 交换机(Exchange):生产者把消息先发送到Broker的Exchange上,再根据不同的规则,再把消息转发给不同的Queue
  • 队列(Queue):真正用来存储消息的部分,每个消费者决定从那个从哪个Queue上读取消息
  • 绑定(Binding):Exchange和Queue之间的关联关系,Exchange和Queue能够理解成”多对多“关系,使用一个关联表就可以把这俩个概念联系起来。
  • 消息(Message):传递的内容

所谓的Exchange和Queue可以理解成”多对多“关系,和数据库中的”多对多“一样。意思是:
一个Exchange可以绑定多个Queue(可以向多个Queue中转发消息)
一个Queue也可以被多个Exchange绑定(也就是一个Queue中的消息能够来自多个Exchange)

在这里插入图片描述

上述数据结构,既需要在内存中存储,也要求在硬盘中存储

  • 内存存储:方便使用
  • 硬盘存储:重启数据不丢失

6.2核心API

对于Broker来说,要实现以下核心API,经过这些API来实现消息队列的基本功能
1、创建交换机
2、销毁交换机
3、创建队列 (queueDeclare)
4. 销毁队列 (queueDelete)
5. 创建绑定 (queueBind)
6. 解除绑定 (queueUnbind)
7. 发布消息 (basicPublish)
8. 订阅消息 (basicConsume)
9. 确认消息 (basicAck)
10. 取消订阅 (basicCancel)
productor和Consumer则经过网络的方式,远程调用这些API,完成生产者消费者模型

关于VirtualHost,对于RabbitMQ来说,VirtualHost也是可能随意创建删除的

6.3交换机类型

对于RabbitMQ来说,主要支持四种交换机类型:

  • Direct
  • Fanout
  • Topic
  • Header
    前三种类型,这里用前三种就是其中 Header这种方式困难,少见,常见的
  • Direct:生产者发送消息时,直接指定被该交换机绑定·的名。
  • Fanout:生产者发送的消息会被复制到该交换机所有队列中。
  • Topic:绑定队列到交换机上时,指定一个字符串为bindingKey。发送消息指定一个字符串为routingKey。当routingKey& bindKey满足一定匹配条件时候,则把消息投递到指定队列

6.4 持久化

Exchange Queue Binding Message等数据都有数据持久化需求。
当主机重启/程序重启,保证上述内容不丢失。

6.5网络通信

生产者和消费者都是客户端程序,Broker则是作为服务器,通过网络进行通信。在网络通信的过程中,客户端部分要提供对应的api,来实现对服务器的操作。

  1. 创建 Connection
  2. 关闭 Connection
  3. 创建 Channel
  4. 关闭 Channel
  5. 创建队列 (queueDeclare)
  6. 销毁队列 (queueDelete)
  7. 创建交换机 (exchangeDeclare)
  8. 销毁交换机 (exchangeDelete)
  9. 创建绑定 (queueBind)
  10. 解除绑定 (queueUnbind)
  11. 发布消息 (basicPublish)
  12. 订阅消息 (basicConsume)
  13. 确认消息 (basicAck)
  14. 取消订阅(basicCancel)
    在Broker的基础上,客户端还要增加Connection管理Channel操作
  • Connection对应一个TCP连接
  • Channel则是Connection中的逻辑通道
    一个Connection可以包含多个Channel。Channel和Channel之间的信息是独立的,不会相互干扰。这样做主要是为了能够更好的复用TCP连接,达到长连接的效果,避免频繁的创建关闭TCP连接。

通过Connection 能够理解成一根网线。Channel则是网线里具体的线缆

在这里插入图片描述

6.6 消息应答

被消费的消息,需要进行应答。应答模式分两种:

  • 自动应答:消费者只要消费了消息,就算应答完毕了,Broker直接删除这个消息。
  • 手动应答:消费者手动调用应答接口,Broker收到应答请求之后,才真正删除这个消息*

手动应答的目的,是为了保证消息确实被消费者处理成功了,在一些对于素材可靠性要求高的场景,常见

7、模块划分

7.1 服务端模块

7.1.1 持久化数据管理中心模块

在数据管理模块中管理交换机,队列,队列绑定,消息等部分数据。
1、交换机管理

  • 管理消息: 名称,类型,是否持久化,是否自动删除标志,其他参数…
  • 否存在就是管理操作:恢复历史信息,声明,删除,获取,判断
    2、队列管理
  • 管理信息:名称,是否持久化标志,是否独有标志,是否自动删除标志,其他参数…
  • 否存在。就是管理操作:恢复历史信息,声明,删除,获取,判断
    3、绑定管理
  • 管理信息:交换机名称,队列名称,绑定主题
  • 管理执行:恢复历史信息,绑定,解绑,接触交换机绑定信息,解除队列关联绑定信息,获取交换机关联绑定信息。
    4、消息管理
  • a、管理信息
    • 属性:消息id,路由主题,持久化模式标志
    • 消息内容
    • 有效标志(持久化需要)
    • 持久化位置(内存中)
    • 持久化消息长度(内存中)
  • b、管理操作:恢复历史消息,向指定队列新增消息,获取指定队列队首消息,确认移除消息
    这几个核心概念数据都应该在内存和硬盘中存储。
  • 以内存存储为主:首要是保证快速查找信息进行处理
  • 以硬盘存储为辅:主要保证服务器重启之后,之前的信息都可能正常保持

7.1.2虚拟机管理模块

因为交换机/队列/绑定都是基于虚拟机为单元整体进行处理的,因此虚拟机是对以上数据管理模块的整合模块
1、虚拟机管理信息
a. 交换机数据管理模块句柄
b. 队列数据管理模块句柄
c. 绑定数据管理模块句柄
d. 消息数据管理模块句柄*
2、虚拟机对外运行
a. 提供虚拟机内交换机声明,交换机删除操作。
b. 供应虚拟机内队列声明,队列删除操作。
c. 提供虚拟机内交换机-队列绑定,解除绑定操作。
d. 获取交换机相关绑定信息
3、虚拟机管理管理
a. 创建虚拟机
b. 查询虚拟机
c. 删除虚拟机

7.1.3 交换路由模块

当客户端发布一条消息到交换机后,这条消息,应该被入队到该交换机绑定哪些队列中?交换路由模块就是决定这件事。
在绑定信息中有一个binding_key.而每条发布的消息中有一个routing_key,能否入队取决于两个要素:交换机类型和key
1、广播:将消息入队到该交换机的所有绑定队列中
2、直接:将消息入队到绑定信息中binding_key与routing_key一致的队列中
3、主题:将消息入队到绑定信息中binding_key与routing_key是匹配成功的队列中
binding_key
是数字字母下划线组成,并且用 . 分成若干部分。
例如:news.music.#,这用于表示交换机绑定的当前队列是一个用于发布音乐新闻的
队列。
•支持 * 和 # 两种通配符, 但是 * # 只能作为 . 切分出来的独立部分, 不能和其他
数字字母混用,
○ 比如 a.*.b 是合法的, a.*a.b 是不合法的○ * 可以匹配任意一个单词(注意是单词不是字母)
○ # 能够匹配任意零个或者多个单词(注意是单词不是字母)
routing_key
是由数据、字母和下划线构成, 并且能够应用 . 划分成若干部分。例如:news.music.pop,这用于表示当前发布的消息是一个流行音乐的新闻.

7.1.4消费者管理模块

消费者是以队列为单元的,因为每个消费者都会在开始的时候订阅一个队列的消息,当队列中有消息后,会将队列消息轮询推送给订阅了该队列了该队列的消费者。

因此操作流程是,从队列关联的消息管理中取出消息,从队列关联的消费者中取出一个消费者,然后将消息推送给消费者(这就是发布订阅中负载均衡的用法)

1、消费者信息:
a. 标识
b. 订阅队列名称
c. 自动应答标志(决定了一条消息推送给消费者后,是否需要等待收到确认后
再删除消息)
d. 消息处理回调函数指针(一个消息发布后调用回调,选择消费者进行推送…)
i. void(const std::string& tag, const BasicProperties& p,const std::string& body)
2. 消费者管理:添加,删除,轮询获取指定队列的消费者,移除队列所有消费者等
操作

7.1.5信道管理模块

本质上,在AMQP模型中,除了通信连接Connection概念外,还有一个Channel的概念,Channel是针对Connection连接的一个更细粒度的通信管道,多个Channel可以使用同一个通信连接Connection进行通信,但是同一个Connection的Channel之间相互独立。

而信道模块就是再次将上述模块进行整合提供服务模块

  1. 管理信息:
    a. 信道 ID
    b. 信道关联的消费者
    c. 信道关联的连接d. 信道关联的虚拟机
    e. 工作线程池(一条消息被发布到队列后,要求将消息推送给订阅了对应队列
    的消费者,过程由线程池完成)
  2. 管理操作:
    a. 提供声明&删除交换机操作(删除交换机的同时删除交换机关联的绑定信息)
    b. 提供声明&删除队列操作(删除队列的同时,删除队列关联的绑定信息,消息,
    消费者信息)
    c. 提供绑定&解绑队列操作
    d. 提供订阅&取消订阅队列消息操作
    e. 提供发布&确认消息操作

7.1.6连接管理模块

本质,仿照构建的服务器是通过muduo库来实现底层通信的,而这里的连接管理,更多的是对muduo库中的Connection进行二次封装管理,并额外给出项目所需管理。

  1. 管理信息:
    a. 连接关联的信道
    b. 连接关联的 muduo 库 Connection
  2. 管理操作:新增连接,删除连接,获取连接,打开信道,关闭信道。

7.1.7 Broker服务器模块

整合以上所有模块,并搭建网络通信服务器,实现与客户端网络通信,能够识别客户
端请求,并提供客户端请求的处理服务。
管理信息:
a. 虚拟机管理模块句柄
b. 消费者管理模块句柄
c. 连接管理模块句柄
d. 工作线程池句柄
e. muduo 库通信所需元素…

7.2 客户端模块

7.2.1 消费者管理

消费者在客户端的存在感比较低,因为在用户的应用角度中,只要创建一个信道后,
在订阅的时候传入了就是就可以利用信道完毕所有的操作,因此对于消费者的感官更多
一个消费者标识,且当前的简单实现也仅仅是一个信道只能创建订阅一个队列,也就
弱化了消费者的存在。就是是只能创建一个消费者,它们一一对应,因此更

  1. 消费者信息:
    a. 标识
    b. 订阅队列名称
    否必须等待收到确认后就是c. 自动应答标志(决定了一条消息推送给消费者后,
    再删除消息)
    d. 消息处理回调函数指针(一个消息发布后调用回调,选择消费者进行推送…)
  2. 消费者管理:添加,删除,轮询获取指定队列的消费者,移除队列所有消费者等
    操作

7.2.2 信道请求模块

与服务端的信道类似,客户端这边在AMQP模型中,也是除了通信连接Connection概念外,还有一个Channel的概念,Channel是针对Connection连接的一个更细粒度的通信管道,多个Channel行采用一个通信连接Connection进行通信,但同一个Connection的Channel之间相互独立。
1、信道管理信息:
a、信道ID
b、信道管理的通信连接
c、信道关联的消费者
d、请求对应的响应信息队列(这里队列使用hash表,以便于查找指定的响应)
e、互斥锁&条件变量(大部分的请求都是阻塞操作,发送请求后需要等到响应才
能继续,不过 muduo 库的通信是异步的,因此需要我们自己在收到响应后,通过
等待的指定响应来进行同步)就是判断是否
2. 信道管理操作:
a. 提供创建信道操作
b. 献出删除信道操作
c. 提供声明交换机操作(强断言-有则 OK,没有则创建)
d. 提供删除交换机e. 提供创建队列运行(强断言-有则 OK,没有则创建)
f. 提供删除队列操作
g. 提供交换机-队列绑定操作
h. 提供交换机-队列解除绑定操作
i. 提供添加订阅操作
j. 提供取消订阅操作
k. 提供发布消息管理

7.2.3 通信连接模块

向用户提供一个用于达成网络通信的 Connection 对象,从其内部可创建出粒度更轻的
Channel 对象,用于与服务端进行网络通信。

  1. 管理信息:
    a. 连接关联的实际用于通信的 muduo::net::Connection 连接
    b. 连接关联的信管理句柄(构建信道的增删查)
    c. 连接关联的 EventLoop 异步循环工作线程
    d. 异步工作线程池(用于对收到服务器推送过来的消息进行处理的线程池)
  2. 管理操作:
    a. 提供创建 Channel 信道的执行
    b. 提供删除 Channel 信道的操作
posted @ 2025-12-18 12:34  clnchanpin  阅读(8)  评论(0)    收藏  举报