C++ - 仿 RabbitMQ 实现消息队列--网络通信协议设计

目录

需求确认

设计应用层协议

定义请求/响应参数


需求确认

回顾 MQ 的交互模型:

其中生产者和消费者都是客户端, 它们都需要通过网络和 Broker Server 进行通信。具体通信的过程我们使用 Muduo 库来实现, 使用 TCP 作为通信的底层协议, 同时在这个基础上自定义应用层协议, 完成客户端对服务器功能的远端调用。 我们要实现的远端调用接口包括:

  1. 创建 channel;
  2. 关闭 channel;
  3. 创建 exchange;
  4. 删除 exchange;
  5. 创建 queue;
  6. 删除 queue;
  7. 创建 binding;
  8. 删除 binding;
  9. 发送 message;
  10. 订阅 message;
  11. 发送 ack;
  12. 返回 message (服务器 -> 客户端)。

设计应用层协议

使用二进制的方式设计应用层协议。

因为 MQMessage 的消息体是使用 Protobuf 进行序列化的,本身是按照二进制存储的,所以不太适合用 json 等文本格式来定义协议。

下面我们设计一下应用层协议:请求/响应报文设计

  • len:4 个字节, 表示整个报文的长度。
  • nameLen: 4 个字节, 表示 typeName 数组的长度。
  • typeName:是个字节数组, 占 nameLen 个字节, 表示请求/响应报文的类型名,作用是分发不同消息到对应的远端接口调用中。
  • protobufData:是个字节数组, 占 len - nameLen - 8 个字节, 表示请求/响应参数数据通过 protobuf 序列化之后的二进制。
  • checkSum:4 个字节, 表示整个消息的校验和, 作用是为了校验请求/响应报文的完整性。

定义请求/响应参数

因为这里的参数需要进行网络传输以及序列化, 所以我们需要将参数定义在 pb 文件中。

复制代码
syntax = "proto3";
package jiuqi;
import "msg.proto";

// 信道的打开与关闭
message openChannelRequest
{
    string rid = 1; // 请求id
    string cid = 2; // 信道id
};

message closeChannelRequest
{
    string rid = 1;
    string cid = 2;
};

// 交换机的声明与删除
message declareExchangeRequest
{
    string rid = 1;
    string cid = 2;
    string ename = 3;
    ExchangeType etype = 4;
    bool durable = 5;
    bool auto_delete = 6;
    map<string, string> args = 7;
};

message deleteExchangeRequest
{
    string rid = 1;
    string cid = 2;
    string ename = 3;
};

// 队列的声明与删除
message declareQueueRequest
{
    string rid = 1;
    string cid = 2;
    string qname = 3;
    bool exclusive = 4;
    bool durable = 5;
    bool auto_delete = 6;
    map<string, string> args = 7;
};

message deleteQueueRequest
{
    string rid = 1;
    string cid = 2;
    string qname = 3;
};

// 队列的绑定与解除绑定
message queueBindRequest
{
    string rid = 1;
    string cid = 2;
    string ename = 3;
    string qname = 4;
    string bindingkey = 5;    
};

message queueUnbindRequest
{
    string rid = 1;
    string cid = 2;
    string ename = 3;
    string qname = 4;
};

// 消息的发布
message basicPublishRequest
{
    string rid = 1;
    string cid = 2;
    string ename = 3;
    string body = 4;
    BasicProperties properties = 5;
};

// 消息的确认
message basicAckRequest
{
    string rid = 1;
    string cid = 2;
    string qname = 3;
    string mid = 4;
};

// 队列的订阅
message basicConsumeRequest
{
    string rid = 1;
    string cid = 2;
    string ctag = 3;  // 消费者标识
    string qname = 4;
    bool auto_ack = 5;
};

// 订阅的取消
message basicCancelRequest
{
    string rid = 1;
    string cid = 2;
    string ctag = 3;
    string qname = 4;
};

// 消息的推送
message basicConsumeResponse
{
    string cid = 1;
    string ctag = 2;
    string body = 3;
    BasicProperties properties = 4;
};

// 通用响应
message basicCommonResponse
{
    string rid = 1;
    string cid = 2;
    bool ok = 3;
};
相关推荐
2501_933329554 小时前
企业舆情处置技术实践:基于AI的智能监测与申诉系统架构解析
人工智能·分布式·架构·系统架构
爱丽_8 小时前
Redis 分布式锁:SET NX、过期时间、续租、可重入、Redlock 与坑
数据库·redis·分布式
ok_hahaha11 小时前
java从头开始-黑马点评-分布式锁-redis实现基础版
java·redis·分布式
传感器与混合集成电路11 小时前
法珀干涉与光栅补偿:井下压力温度一体化光纤监测技术
分布式
@insist12312 小时前
数据库系统工程师-分布式数据库与数据仓库核心考点及应用体系
数据库·数据仓库·分布式·软考·数据库系统工程师·软件水平考试
XDHCOM13 小时前
TP5框架Redis分布式缓存实战,解决高并发场景下的数据一致性问题
redis·分布式·缓存
Fzuim13 小时前
从CLI到分布式智能体:重新理解AI Agent的演进路径与工程现实
人工智能·分布式·ai·agent·agentic
_院长大人_16 小时前
Spring Boot 3.3 + Atomikos 分布式事务日志路径配置踩坑记录
spring boot·分布式·后端
Data 实验室16 小时前
TaskPyro “小龙虾版本”专业爬虫管理平台来了:AI+分布式+IM 机器人,一套搞定企业级爬虫调度
人工智能·分布式·爬虫
想你依然心痛16 小时前
HarmonyOS 5.0教育行业解决方案:基于分布式能力的沉浸式智慧课堂系统
分布式·wpf·harmonyos