当前位置: 首页 > article >正文

篇章五 项目创建

目录

1.创建一个SpringBoot项目

2.创建核心类

2.1 Exchange类

2.2 MessageQueue类

2.3 Binding类

2.4 Message类

1.Message的组成

2.逻辑删除

3.工厂方法

4.序列化与反序列化

5.offsetBeg和offsetEnd

1.创建一个SpringBoot项目

1.点击

2.填写表单

3.添加依赖

2.创建核心类

创建好Spring Boot项目就可以开始创建核心类了

消息队列中核心概念:

1.交换机

2.队列

3.绑定

4.消息

都存在于Broker Server中

2.1 Exchange类

1.关于持久化的理解

// 交换机是否要持久化存储 true 需要持久化; false 不必持久化
private boolean durable = false;

有些交换机,队列,绑定,是需要持久化的,有些则不需要,所以可以设置开关来让用户决定是否需要持久化

2.关于arguments的理解

RabbitMQ中 Exchange的 x-arguments

参考网址https://www.rabbitmq.com/docs/exchanges#ae

2.2 MessageQueue类

所需要的属性及注释

// 队列的身份标识
private String name;

// 队列是否持久化 true 表示持久化保存
private boolean durable = false;

// 队列是否独占 ture 表示这个队列只能被一个消费者使用
// 并未实现该功能(留着扩展)(RabbitMQ实现了)
private boolean exclusive = false;

// 如果当前队列 没人(消费者)使用 就会自动删除
// 并未实现自动删除功能(留着扩展)(RabbitMQ实现了)
private boolean autoDelete = false;

// 创建队列时 指定的一些额外的参数选项
// 并未实现该功能(留着扩展)(RabbitMQ实现了)
private Map<String, Object> arguments = new HashMap<>();

2.3 Binding类

public class Binding {private String exchangeName;private String queueName;// 支持 TOPIC主题交换机 相当于 出题角色private String bindingKey;public String getExchangeName() {return exchangeName;}public void setExchangeName(String exchangeName) {this.exchangeName = exchangeName;}public String getQueueName() {return queueName;}public void setQueueName(String queueName) {this.queueName = queueName;}public String getBindingKey() {return bindingKey;}public void setBindingKey(String bindingKey) {this.bindingKey = bindingKey;}
}

为什么Binding没有durable 、autoDelete 这两个属性 ?

因为Exchange或者MessageQueue中有一个没有持久化,单独持久化他们的Binding是没有意义的。

2.4 Message类

public class Message implements Serializable {// Massage 最核心的部分private BasicProperties basicProperties = new BasicProperties();private byte[] body;// 以下是: 辅助属性// 如果要存储到文件中(持久化)// 一个文件会存储很多的消息, 如何找到某个消息, 在文件中的具体位置?// 使用下列的 两个偏移量 来进行表示 [offsetBeg, offsetEnd)// 这两个属性并不需要序列化保存到文件中// 1.此时消息被写入文件后 所在的位置固定 并不需要存储这两个属性// 2.属性存在的目的:为了让内存中的Message对象, 能够快速找到对应的硬盘上的Message的位置private transient long offsetBeg = 0; // 消息数据的开头距离文件开头的位置偏移(字节)private transient long offsetEnd = 0; // 消息数据的结尾距离文件开头的位置便宜(字节)// 使用这个属性表示该消息在文件中是否是有效消息(逻辑删除)// 0x1 表示有效  0x0 表示无效private byte isValid = 0x1;// 创建一个工厂方法 封装 创建Message对象的而过程// 此方法 创建的Message对象 会 自动生成 唯一的MessageId// 如果 routingKey 和 basicProperties 中的 routingKey 冲突了 以外面为主public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body){Message message = new Message();if (basicProperties != null) {message.setBasicProperties(basicProperties);}// 此处加上 "M-" 前缀 区分不同实体的IDmessage.setMessageId("M-" + UUID.randomUUID());message.basicProperties.setRoutingKey(routingKey);message.body = body;return message;}public String getMessageId() {return basicProperties.getMessageId();}public void setMessageId(String messageId) {basicProperties.setMessageId(messageId);}public String getRoutingKey() {return basicProperties.getRoutingKey();}public void setRoutingKey(String routingKey) {basicProperties.setRoutingKey(routingKey);}public int getDeliverMode() {return basicProperties.getDeliverMode();}public void setDeliverMode(int mode) {basicProperties.setDeliverMode(mode);}public BasicProperties getBasicProperties() {return basicProperties;}public void setBasicProperties(BasicProperties basicProperties) {this.basicProperties = basicProperties;}public byte[] getBody() {return body;}public void setBody(byte[] body) {this.body = body;}public long getOffsetBeg() {return offsetBeg;}public void setOffsetBeg(long offsetBeg) {this.offsetBeg = offsetBeg;}public long getOffsetEnd() {return offsetEnd;}public void setOffsetEnd(long offsetEnd) {this.offsetEnd = offsetEnd;}public byte getIsValid() {return isValid;}public void setIsValid(byte isValid) {this.isValid = isValid;}}

1.Message的组成

1.属性部分 BasicProperties

2.正文部分 byte[]

为什么正文部分不用 String[]?

因为String[] 只能存储文本,所以采用byte[] 增加 通用性

2.逻辑删除

字段解析:private byte isValid = 0x1;

与数据库相同,删除数据使用逻辑删除。不是真正的删除而是标记为无效。

3.工厂方法

// 创建一个工厂方法 封装 创建Message对象的而过程// 此方法 创建的Message对象 会 自动生成 唯一的MessageId// 如果 routingKey 和 basicProperties 中的 routingKey 冲突了 以外面为主public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body){Message message = new Message();if (basicProperties != null) {message.setBasicProperties(basicProperties);}// 此处加上 "M-" 前缀 区分不同实体的IDmessage.setMessageId("M-" + UUID.randomUUID());message.basicProperties.setRoutingKey(routingKey);message.body = body;return message;}

为什么不用构造方法?

        使用构造方法也能达成同样目的,但是工厂方法可以让名字更清晰,毕竟工厂方法就是来填构造 方法不能随便取名字的坑。

4.序列化与反序列化

准备工作:实现一个Serializable接口(标记接口)

此处准备使用标准库自带的方式进行序列化和反序列化,为什么不使用Json方式?

Json的本质是文本格式

而此处的Message里面存储的是二进制

5.offsetBeg和offsetEnd

offsetBeg 和 offsetEnd 不需要序列化

1.此时消息被写入文件后 所在的位置固定 并不需要存储这两个属性

2.属性存在的目的:为了让内存中的Message对象, 能够快速找到对应的硬盘上的Message的位置

http://www.lryc.cn/news/2383396.html

相关文章:

  • Ntfs!ATTRIBUTE_RECORD_HEADER结构$INDEX_ROOT=0x90的一个例子
  • AGI大模型(30):LangChain链的基本使用
  • 代码随想录算法训练营第六十六天| 图论11—卡码网97. 小明逛公园,127. 骑士的攻击
  • [创业之路-364]:企业战略管理案例分析-5-战略制定-宇树科技的使命、愿景、价值观的演变过程
  • React--函数组件和类组件
  • Flask 路由装饰器:从 URL 到视图函数的优雅映射
  • DDoS防护实战——从基础配置到高防IP部署
  • aws平台s3存储桶夸域问题处理
  • HOT100(二叉树)
  • 【vue-text-highlight】在vue2的使用教程
  • pycharm无法正常调试问题
  • springboot3.4.5-springsecurity+session
  • 网络安全利器:蜜罐技术详解
  • Leetcode百题斩-哈希
  • MySQL替换瀚高数据库报错: TO_DAYS()不存在(APP)
  • EXIST与JOIN连表比较
  • 【Linux】利用多路转接epoll机制、ET模式,基于Reactor设计模式实现
  • 【jvm第7集】jvm调优工具(命令行工具)
  • react中运行 npm run dev 报错,提示vite.config.js出现错误 @esbuild/win32-x64
  • 鸿蒙UI开发——Builder与LocalBuilder对比
  • 关于光谱相机的灵敏度
  • Model 速通系列(一)nanoGPT
  • 微信小程序中,一个页面的数据改变了,怎么通知另一个页面也改变?
  • MySQL--day4--排序与分页
  • 自动化测试脚本点击运行后,打开Chrome很久??
  • iOS热更新技术要点与风险分析
  • 系统架构设计(十二):统一过程模型(RUP)
  • 系分论文《论软件系统安全分析和应用》
  • Mac安装redis
  • srs-7.0 支持obs推webrtc流