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

2024.2.29 模拟实现 RabbitMQ —— 项目展示

目录

项目介绍

核心功能

核心技术

演示直接交换机

演示扇出交换机

演示主题交换机


项目介绍

  • 此处我们模拟 RabbitMQ 实现了一个消息队列服务器

核心功能

  • 提供了 虚拟主机交换机队列绑定消息 概念的管理
  • 九大核心 API 创建队列销毁队列创建交换机销毁交换机创建绑定解除绑定发布消息订阅消息确认消息
  • 实现了三种典型的消息转换方式 直接交换机(Direct)扇出交换机(Fanout)主题交换机(Topic)
  • 交换机队列绑定 使用 SQLite 数据库持久化,消息 使用文件持久化
  • 基于 TCP + 自定义应用层协议 实现生产者/消费者和 Broker Server 之间的交互工作

核心技术

  • Spring Boot / MyBatis / Lombok
  • SQLite
  • TCP

  • 关于该项目的需求分析,可点击下方链接跳转

模拟实现 RabbitMQ —— 需求分析


  • 关于该项目的核心类,可点击下方链接跳转

模拟实现 RabbitMQ —— 实现核心类


  • 关于该项目的数据库操作,可点击下方链接跳转

模拟实现 RabbitMQ —— 数据库操作


  • 关于该项目的消息持久化,可点击下方链接跳转

模拟实现 RabbitMQ —— 消息持久化


  • 关于该项目的内存数据管理,可点击下方链接跳转

模拟实现 RabbitMQ —— 内存数据管理


  • 关于该项目的虚拟机设计,可点击下方链接跳转

模拟实现 RabbitMQ —— 虚拟主机设计


  • 关于该项目的交换机转发规则,可点击下方链接跳转

模拟实现 RabbitMQ —— 实现转发规则


  • 关于该项目的消费逻辑,可点击下方链接跳转

模拟实现 RabbitMQ —— 实现消费消息逻辑


  • 关于该项目网络通信设计,可点击下方链接跳转

模拟实现 RabbitMQ —— 网络通信设计(服务器)

模拟实现 RabbitMQ —— 网络通信设计(客户端)

演示直接交换机

  • 简单写一个 demo 模拟 跨主机的生产者消费者模型
  • 此处为了方便,就在本机演示

  • 此处我们创建的交换机类型为 直接交换机

1、在 Spring Boot 项目的启动类中创建 Broker Server,绑定端口并启动!

@SpringBootApplication
public class DemoApplication {public static ConfigurableApplicationContext context;public static void main(String[] args) throws IOException {context = SpringApplication.run(DemoApplication.class, args);BrokerServer brokerServer = new BrokerServer(9090);brokerServer.start();}
}

2、编写生产者代码

/*
* 这个类用来表示一个生产着
* 通常这是一个单独的服务器程序
* */
public class DemoProducer {public static void main(String[] args) throws IOException, InterruptedException {System.out.println("启动生产者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();//        创建交换机和队列channel.exchangeDeclare("testExchange", ExchangeType.DIRECT,true,false,null);channel.queueDeclare("testQueue",true,false,false,null);//        创建一个消息并发送byte[] body = "hello".getBytes();boolean ok = channel.basicPublish("testExchange","testQueue",null,body);System.out.println("消息投递完成! ok = " + ok);Thread.sleep(500);channel.close();connection.close();}
}

3、编写消费者代码

/*
* 这个类表示一个消费者
* 通常这个类也应该是在一个独立的服务器中被执行
* */
public class DemoConsumer {public static void main(String[] args) throws IOException, InterruptedException, MqException {System.out.println("启动消费者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare("testExchange",ExchangeType.DIRECT,true,false,null);channel.queueDeclare("testQueue",true,false,false,null);channel.basicConsume("testQueue", true, new Consumer() {@Overridepublic void handleDelivery(String consumerTag, BasicProperties basicProperties, byte[] body) throws MqException, IOException {System.out.println("[消费数据] 开始!");System.out.println("consumerTag = " + consumerTag);System.out.println("basicProperties = " + basicProperties);String bodyString = new String(body,0,body.length);System.out.println("body = " + bodyString);System.out.println("[消费数据] 结束!");}});//        由于消费者也不知道生产者要生产多少消息,就在这里通过这个循环模拟一直等待消费while (true) {Thread.sleep(500);}}
}

4、启动 Spring Boot 项目(启动 Broker Server)


5、运行消费者代码


6、运行生产者代码


7、继续观察消费者的控制台

演示扇出交换机

  • 此处我们创建的交换机类型为 扇出交换机

 1、编写生产者代码

/** 这个类用来表示一个生产着* 通常这是一个单独的服务器程序* */
public class DemoProducer {public static void main(String[] args) throws IOException, InterruptedException {System.out.println("启动生产者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();
//        创建交换机channel.exchangeDeclare("testExchange", ExchangeType.FANOUT,true,false,null);
//        创建一个消息并发送byte[] body = "hello".getBytes();boolean ok = channel.basicPublish("testExchange","",null,body);System.out.println("消息投递完成! ok = " + ok);Thread.sleep(500);channel.close();connection.close();}
}

3、编写消费者A 代码

/** 这个类表示一个消费者A* 通常这个类也应该是在一个独立的服务器中被执行* */
public class DemoConsumerA {public static void main(String[] args) throws IOException, InterruptedException, MqException {System.out.println("启动消费者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();
//        创建交换机channel.exchangeDeclare("testExchange",ExchangeType.FANOUT,true,false,null);
//        创建队列channel.queueDeclare("testQueue1",true,false,false,null);
//        设置绑定channel.queueBind("testQueue1","testExchange","");
//        订阅消息channel.basicConsume("testQueue1", true, new Consumer() {@Overridepublic void handleDelivery(String consumerTag, BasicProperties basicProperties, byte[] body) throws MqException, IOException {System.out.println("[testQueue1 消费数据] 开始!");System.out.println("consumerTag = " + consumerTag);System.out.println("basicProperties = " + basicProperties);String bodyString = new String(body,0,body.length);System.out.println("body = " + bodyString);System.out.println("[testQueue1 消费数据] 结束!");}});//        由于消费者也不知道生产者要生产多少消息,就在这里通过这个循环模拟一直等待消费while (true) {Thread.sleep(500);}}
}

4、编写消费者B 代码

/** 这个类表示一个消费者B* 通常这个类也应该是在一个独立的服务器中被执行* */
public class DemoConsumerB {public static void main(String[] args) throws IOException, InterruptedException, MqException {System.out.println("启动消费者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();
//        创建交换机channel.exchangeDeclare("testExchange", ExchangeType.FANOUT,true,false,null);
//        创建队列channel.queueDeclare("testQueue2",true,false,false,null);
//        设置绑定channel.queueBind("testQueue2","testExchange","");
//        订阅消息channel.basicConsume("testQueue2", true, new Consumer() {@Overridepublic void handleDelivery(String consumerTag, BasicProperties basicProperties, byte[] body) throws MqException, IOException {System.out.println("[testQueue1 消费数据] 开始!");System.out.println("consumerTag = " + consumerTag);System.out.println("basicProperties = " + basicProperties);String bodyString = new String(body,0,body.length);System.out.println("body = " + bodyString);System.out.println("[testQueue1 消费数据] 结束!");}});//        由于消费者也不知道生产者要生产多少消息,就在这里通过这个循环模拟一直等待消费while (true) {Thread.sleep(500);}}
}

5、启动 Spring Boot 项目(启动 Broker Server)


6、运行消费者A 代码


7、运行消费者B 代码


8、运行生产者代码


9、继续观察消费者A 的控制台


10、继续观察消费者B 的控制台

演示主题交换机

  • 此处我们创建的交换机为 主题交换机

 1、编写生产者代码

/** 这个类用来表示一个生产着* 通常这是一个单独的服务器程序* */
public class DemoProducer {public static void main(String[] args) throws IOException, InterruptedException {System.out.println("启动生产者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();//        创建交换机和队列channel.exchangeDeclare("testExchange", ExchangeType.TOPIC,true,false,null);channel.queueDeclare("testQueue",true,false,false,null);//        创建消息A 并发送byte[] body = "hello".getBytes();boolean ok = channel.basicPublish("testExchange","ccc.aaa.bbb",null,body);System.out.println("消息投递完成! ok = " + ok);//        创建消息B 并发送body = "hi".getBytes();ok = channel.basicPublish("testExchange","aaa.bbb",null,body);System.out.println("消息投递完成! ok = " + ok);Thread.sleep(500);channel.close();connection.close();}
}

3、编写消费者代码

/** 这个类表示一个消费者* 通常这个类也应该是在一个独立的服务器中被执行* */
public class DemoConsumer {public static void main(String[] args) throws IOException, InterruptedException, MqException {System.out.println("启动消费者!");ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort(9090);Connection connection = connectionFactory.newConnection();Channel channel = connection.createChannel();
//        创建交换机channel.exchangeDeclare("testExchange", ExchangeType.TOPIC,true,false,null);
//        创建队列channel.queueDeclare("testQueue",true,false,false,null);
//        设置绑定channel.queueBind("testQueue","testExchange","*.aaa.bbb");
//        订阅消息channel.basicConsume("testQueue", true, new Consumer() {@Overridepublic void handleDelivery(String consumerTag, BasicProperties basicProperties, byte[] body) throws MqException, IOException {System.out.println("[消费数据] 开始!");System.out.println("consumerTag = " + consumerTag);System.out.println("basicProperties = " + basicProperties);String bodyString = new String(body,0,body.length);System.out.println("body = " + bodyString);System.out.println("[消费数据] 结束!");}});
//        由于消费者也不知道生产者要生产多少消息,就在这里通过这个循环模拟一直等待消费while (true) {Thread.sleep(500);}}
}

4、启动 Spring Boot 项目(启动 Broker Server)


5、运行消费者代码


6、运行生产者代码


7、继续观察消费者的控制台

相关文章:

2024.2.29 模拟实现 RabbitMQ —— 项目展示

目录 项目介绍 核心功能 核心技术 演示直接交换机 演示扇出交换机 演示主题交换机 项目介绍 此处我们模拟 RabbitMQ 实现了一个消息队列服务器 核心功能 提供了 虚拟主机、交换机、队列、绑定、消息 概念的管理九大核心 API 创建队列、销毁队列、创建交换机、销毁交换机、…...

React htmlfor

注意,在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。 在React中,当我们需要为一个表单元素设置标签时,可以使用htmlFor属性。它…...

现代化数据架构升级:毫末智行自动驾驶如何应对年增20PB的数据规模挑战?

毫末智行是一家致力于自动驾驶的人工智能技术公司,其前身是长城汽车智能驾驶前瞻分部,以零事故、零拥堵、自由出行和高效物流为目标,助力合作伙伴重塑和全面升级整个社会的出行及物流方式。 在自动驾驶领域中,是什么原因让毫末智行…...

理解Stable Diffusion、LoRA、Dreambooth、Hypernetworks、Textual Inversion、Checkpoint

前言 在深度学习和人工智能的领域中,模型生成和调整技术的快速发展为创造性内容的自动化提供了新的可能性。本文将介绍四种重要的模型技术——Stable Diffusion、LoRA、Dreambooth、和Hypernetworks——它们在生成艺术、个性化模型调整和网络结构设计方面各自的特点…...

spring boot3登录开发-2(1图形验证码接口实现)

⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途。 目录 前置条件 内容简介 图形验证码接口实现 导入糊涂工具依赖 接口分析 编写验证码接口 测试验证码接口 前置条件 …...

网络编程中的问题总结

1、服务端重启后bind失败,因为TCP 套接字状态 TIME_WAIT 引起,该状态在套接字关闭后约保留 2 到 4 分钟。在 TIME_WAIT 状态退出之后,套接字被删除,该地址才能被重新绑定而不出问题。可以通过setsockopt()设置Socket描述符的选项S…...

数据结构-关键路径

介绍 在AOV网的基础上,如果用对应边来表示活动持续时间,这种有向图被称为AOE网在AOE网中,入度为0的为源点,出度为0的为汇点,整张网看做是一件事情完成的过程,那么这两个点就是事情的开始和结束。每个活动持…...

进程间通信学习笔记(共享内存)

内存映射概念: 共享内存可以通过mmap()映射普通文件使一个磁盘文件与内存中的一个缓冲区相映射,进程可以像访问普通文件一样对文件进行访问,不必再强调read,write。 mmap的优点: 实现了用户空间和内核空间的高效交互方式 mmap的…...

ChatGPT学习第三周

📖 学习目标 ChatGPT在各行各业的应用 探索ChatGPT在不同领域(如教育、客户服务等)的实际应用案例。 ChatGPT的局限性和挑战 讨论ChatGPT面临的挑战,包括偏见、误解及其限制。 ✍️ 学习活动 学习资料 《人工智能通用大模型(…...

R语言混合效应(多水平/层次/嵌套)模型及贝叶斯实现技术应用

回归分析是科学研究中十分重要的数据分析工具。随着现代统计技术发展,回归分析方法得到了极大改进。混合效应模型(Mixed effect model),即多水平模(Multilevel model)/分层模型(Hierarchical Model)/嵌套模…...

[C++]使用C++部署yolov9的tensorrt模型进行目标检测

部署YOLOv9的TensorRT模型进行目标检测是一个涉及多个步骤的过程,主要包括准备环境、模型转换、编写代码和模型推理。 首先,确保你的开发环境已安装了NVIDIA的TensorRT。TensorRT是一个用于高效推理的SDK,它能对TensorFlow、PyTorch等框架训…...

eureka注册中心做了哪些事情/原理?

1.服务注册: 将eureka client发送过来的元数据存储到注册表中 2.服务续约: eureka client默认会每30秒向eureka server发送一次心跳来进行服务续约,通过这一行动来表示自己没有出现故障; 3.服务…...

c语言经典测试题4

1.题1 #include <stdio.h>//没有break的话&#xff0c;输入什么都会往下一直执行下去&#xff0c;而且default在最后就会全都执行 int main() {char c;int v0 0, v1 0, v2 0;do{switch (c getchar())// 输入ADescriptor{casea:caseA:casee:caseE:casei:caseI:caseo:…...

设计模式(五)-观察者模式

前言 实际业务开发过程中&#xff0c;业务逻辑可能非常复杂&#xff0c;核心业务 N 个子业务。如果都放到一块儿去做&#xff0c;代码可能会很长&#xff0c;耦合度不断攀升&#xff0c;维护起来也麻烦&#xff0c;甚至头疼。还有一些业务场景不需要在一次请求中同步完成&…...

MySQL-七种SQL优化

一、插入数据 普通插入&#xff1a; 采用批量插入&#xff08;一次插入的数据不建议超过1000条&#xff09; insert into tb_test values(1,Tom),(3, Cat),(3, Jerry)....手动提交事务 start transaction; insert into tb_test values(1,Tom),(3, Cat),(3, Jerry); insert …...

针对Umi、React中遇到的 “xxxx”不能用作 JSX 组件 问题解决方案

一、处理方案 这是因为"types/react"、"types/react-dom"在子依赖中使用的版本不一致导致&#xff0c;一般情况npm会自动帮我们处理版本不一致的问题。如果npm处理不了&#xff0c;就需要我们自己手动处理在package.json中添加一项配置 {name:"test&…...

蓝桥杯备战刷题one(自用)

1.被污染的支票 #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() {int n;cin>>n;vector<int>L;map<int,int>mp;bool ok0;int num;for(int i1;i<n;i){cin>>nu…...

设计模式(十) - 工厂方式模式

前言 在此前的设计模式&#xff08;四&#xff09;简单工厂模式中我们介绍了简单工厂模式&#xff0c;在这篇文章中我们来介绍下工厂方法模式&#xff0c;它同样是创建型设计模式&#xff0c;而且又有些类似&#xff0c;文章的末尾会介绍他们之间的不同。 1.工厂方法模式简介 …...

http协议基础与Apache的简单介绍

一、相关介绍&#xff1a; 互联网&#xff1a;是网络的网络&#xff0c;是所有类型网络的母集因特网&#xff1a;世界上最大的互联网网络。即因特网概念从属于互联网概念。习惯上&#xff0c;大家把连接在因特网上的计算机都成为主机。万维网&#xff1a;WWW&#xff08;world…...

RabbitMQ的死信队列和延迟队列

文章目录 死信队列如何配置死信队列死信队列的应用场景Spring Boot实现RabbitMQ的死信队列 延迟队列方案优劣&#xff1a;延迟队列的实现有两种方式&#xff1a; 死信队列 1&#xff09;“死信”是RabbitMQ中的一种消息机制。 2&#xff09;消息变成死信&#xff0c;可能是由于…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...