SpringBoot整合RabbitMQ及其原理分析

news2024/12/29 10:29:35

上一篇:RabbitMQ基础知识

1、相关依赖

这里无需指定版本号,让其跟着SpringBoot版本走。本示例使用SpringBoot版本号为2.7.10。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

2、生产者、消费者

创建两个SpringBoot应用,模拟消息生产者与消费者【publisher、consumer】。

2-1生产者

编写配置文件,用户名和密码等自行修改 这里虚拟机的名称是上一篇文章中新建的。

server.port=8082
#rabbitmq服务器ip
spring.rabbitmq.host=localhost
#rabbitmq的端口
spring.rabbitmq.port=5672
#用户名
spring.rabbitmq.username=用户名
#密码
spring.rabbitmq.password=密码
#配置虚拟机
spring.rabbitmq.virtual-host=demo

声明交换机、队列并绑定:

@Configuration
public class RabbitMqConfig {

    @Bean
    public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public MessageConverter jackson2JsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public DirectExchange getExchange(){
        return new DirectExchange("directExchange",false,false);
    }

    @Bean
    public Queue getQueue(){
        return new Queue("publisher.addUser",true,false,false);
    }

    @Bean
    public Binding getBinding(DirectExchange exchange,Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with("publisher.addUser");
    }
}

新建User实体类

@Data
public class User {
    private Long id;
    private String name;
    private String desc;
}

在方法中使用RabbitTemplate来发送消息:

public interface PublisherService {

    /**
     * 添加用户
     * @param user 用户信息
     */
    void addUser(User user);

}
@RequiredArgsConstructor
@Service
public class PublisherServiceImpl implements PublisherService{

    private final RabbitTemplate rabbitTemplate;

    @Override
    public void addUser(User user) {
        rabbitTemplate.convertAndSend("directExchange","publisher.addUser",user);
    }
}

以上需要注意的就是交换机的名称队列名routingKey。示例中使用的是直连交换机,routingKey需要和队列名保持一致。不懂的可以查看上一篇文章。

controller:

@RequiredArgsConstructor
@RestController
@RequestMapping("/user")
public class UserController {


    private final PublisherService publisherService;

    @PostMapping("/add")
    public void add(){
        User user = new User();
        user.setId(1000L);
        user.setName("黄忠");
        user.setDesc("老兵不死,只是逐渐凋零");
        publisherService.addUser(user);
    }

}

2-2消费者

消费者的配置和生产者一样,不赘述了,直接看代码:

@Service
@Slf4j
public class ConsumerService {


    @RabbitListener(queues ="publisher.addUser")
    public void addUser(String userStr){
        User user = JSONObject.parseObject(userStr,User.class);
        log.info(user.toString());
    }
}

@RabbitListener 注解是指定某方法作为消息消费的方法,指定队列名称。@RabbitListener 如果标注在类上,需配合 @RabbitHandler 注解一起使用,根据接受的参数类型进入具体的方法中。

2-3测试

消费端在启动时可能会报找不到交换机或队列,只需要让生产者发送一次消息,从控制台就可以看到相关的交换机和队列等信息了。

可以看到消费者成功消费了消息:

3、消费流程

通过上述操作,我们已经会简单地使用RabbitMQ了,接下来了解一下它的整个流程。如此可以让我们掌握的更牢固。

生产者:

  • 生产者连接到Message Broker【也就是RabbitMQ服务】,建立一个连接( Connection)开启一个信道(Channel)。
  • 生产者声明一个交换机,并设置相关属性,比如交换机类型、是否持久化等。
  • 生产者声明一个队列并设置相关属性。
  • 生产者通过路由键【Routing Key】将交换机和队列绑定。
  • 生产者发送消息至RabbitMQ Broker,其中包含路由键、交换器等信息。
  • 相应的交换机根据接收到的路由键查找相匹配的队列。
  • 如果找到,则将从生产者发送过来的消息存入相应的队列中。
  • 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
  • 关闭信道。
  • 关闭连接。

消费者:

  • 消费者连接到RabbitMQ Broker ,建立一个连接(Connection),开启一个信道(Channel) 。
  • 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,
  • 等待RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息。
  • 消费者确认(ack) 接收到的消息。
  • RabbitMQ 从队列中删除相应己经被确认的消息。
  • 关闭信道。
  • 关闭连接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562159.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SaaS系统平台,如何兼顾客户的个性化需求?

在当今数字化的商业环境中&#xff0c;SaaS系统已经成为企业运营的重要组成部分之一。 SaaS系统平台的好处是显而易见的&#xff0c;可以将业务流程数字化&#xff0c;从而帮助企业提高效率并节省成本。 但是&#xff0c;由于每个企业的业务都不尽相同&#xff0c;所以在选择Sa…

GuLi商城-前端基础ES6

ES6 ES6全称ECMAScript6.0是JavaScript语言的下一代标准。 ECMAScript是浏览器脚本语言的规范&#xff0c;而我们熟悉的各种js语言&#xff0c;如JavaScript则是规范的具体实 现。 新建一个ES6文件夹&#xff0c;shift!按着不动&#xff0c;回车&#xff0c;可以快速生成模…

图神经网络:(处理点云)PPFNet的实现

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 前言文献阅读代码实操历史遗留问题 前言 本篇文章接上一篇文章…

【LeetCode: 410. 分割数组的最大值 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

这七种常见的路由协议,每一个网络工程师都应该知道!

你好&#xff0c;这里是网络技术联盟站。 路由协议是网络中非常重要的一个概念&#xff0c;它负责将数据包从源节点传递到目的节点。路由协议定义了网络中不同路由器之间的通信规则和数据传输方式&#xff0c;以便有效地将数据包从源地址传输到目标地址。在网络领域中&#xf…

基于无人机辅助边缘计算系统的节能卸载策略

源自&#xff1a;《系统工程与电子技术》 作者&#xff1a;余雪勇 朱烨 邱礼翔 朱洪波 摘 要 针对复杂地形中地面基础设施无法有效提供可靠通信和密集算力的问题,首先提出一种基于无人机(unmanned aerial vehicle, UAV)托管计算资源的卸载方案。考虑用户终端的计算需…

提升网站访问性的10个步骤优化

第一步,检查 不允许空,不允许过长,简洁明了。 是第一个可以访问到内容的元素,所以一定要非常重视。当用户切换浏览器Tab标签的时候,一定最先听到 标记的内容。Title一定要能代表当前页面的主题。这里的要求和SEO最佳实践几乎一致。 第二步,提供文字替代方案。 走查网页…

【LeetCode】238. 除自身以外数组的乘积

238. 除自身以外数组的乘积&#xff08;中等&#xff09; 方法一&#xff1a;左右乘积列表 思路 除了 nums[i] 以外各元素的积&#xff0c;就等同于 nums[i] 左边元素的乘积 * 右边元素的乘积&#xff0c;因此&#xff0c;我们可以计算出两个乘积列表 &#xff0c;最后再经过一…

2023-05-23 题目

1、在java中定义一个无参的构造方法的作用&#xff1a; 在java程序执行子类的构造方法之前&#xff0c;如果是没有super()来调用父类的特定的构造方法&#xff0c;则会调用父类中没有参数的构造方法。 如果java中没有定义无参的方法&#xff0c;且没有指定super()方法&#x…

深眸科技探索AI机器视觉技术,助力密封圈缺陷识别检出率达99.8%

密封圈作为一种具有良好性能的密封材料&#xff0c;在工业领域具有极其广泛的应用&#xff0c;在汽车、船舶、管道、家用电器等多行业都能看见它的身影&#xff0c;广阔的市场需求促就密封圈产业的蓬勃发展。 密封圈属于大批量生产&#xff0c;在生产过程中难免会出现瑕疵品&a…

zabbix监控系统

一、Zabbix概述 1、使用zabbix的原因 作为一个运维&#xff0c;需要会使用监控系统查看服务器状态以及网站流量指标&#xff0c;利用监控系统的数据去了解上线发布的结果&#xff0c;和网站的健康状态。 利用一个优秀的监控软件&#xff0c;我们可以: ●通过一个友好的界面进…

vue 3.0使用 iframe 标签引入本地HTML页面,并实现数据交互

文章目录 1. 问题总结2. vue中引入html页面3. vue向html传递数据4. html向vue传递数据 1. 问题总结 最近在做vue的项目时候&#xff0c;需要引入本地html页面&#xff0c;中间遇到了很多问题&#xff0c;费时又费力&#xff0c;因此记录下来&#xff0c;以备不时之需&#xff…

顺序表 ArrayList

目录 1. 概念 2. ArrayList集合框架图 3.ArrayList常见的方法 4. 自己实现ArrayList&#xff08;Integer&#xff09; 4.1 ArrayList构造 4.2 ArrayList容量的扩容 4.3 判断空满 4.4 pos坐标是否合法&#xff08;含有&#xff09; 4.5 ArrayList的增删元素 4.6 包含元…

操作系统原理 —— 死锁的概念(十七)

什么是死锁 什么是死锁&#xff0c;如果你是个程序员&#xff0c;那么这概念肯定是不陌生的&#xff0c;死锁通常是指&#xff0c;在并发环境下&#xff0c;各个进程因竞争资源而造成一种相互等待的现象&#xff0c;导致的结果就是各个进程都处于阻塞状态&#xff0c;无法往下…

老司机解读香农定理、奈奎斯特定理、编码与调制

工程师都会考虑一个问题&#xff1a;信道上到底可以传输多大的数据&#xff0c;或者指定的信道上的极限传输率是多少。这就是信道容量的问题。例如&#xff0c;在xDSL系统中&#xff0c;我们使用的传输介质是仅有几兆带宽的电话线&#xff0c;而上面要传送几兆、十几兆甚至几十…

cuda编程学习——基础知识介绍!干货向(三)

本文主要内容为介绍CUDA编程前的一些基础知识 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 1&#xff1a;并行计算 并行程序可以分为 指令并行&#xff1…

还在使用System.out+System.currentTimeMillis打印耗时?Xrebel是你不可或缺的神器!

1、概述 在Java应用程序中&#xff0c;性能是至关重要的。由于Java应用程序通常在高并发环境中运行&#xff0c;并处理大量数据&#xff0c;因此需要确保其能够高效地运行。为了帮助开发人员更好地实现Java应用程序的性能调优&#xff0c;ZeroTurnaround推出了XRebel。 XRebe…

测试用例的设计方法(全)

等价类划分方法 一.方法简介 1.定义 是把所有可能的输入数据,即程序的输入域划分成若干部分&#xff08;子集&#xff09;,然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。 2.划分等价类&#xff1a; 等价…

Stimulsoft 报表开发工具支持Laravel框架!一起来看~

Stimulsoft Reports 是一款报告编写器&#xff0c;主要用于在桌面和Web上从头开始创建任何复杂的报告。可以在大多数平台上轻松实现部署&#xff0c;如ASP.NET, WinForms, .NET Core, JavaScript, WPF, Angular, Blazor, PHP, Java等&#xff0c;在你的应用程序中嵌入报告设计器…

2023-05-24 LeetCode每日一题(T 秒后青蛙的位置)

2023-05-24每日一题 一、题目编号 1377. T 秒后青蛙的位置二、题目链接 点击跳转到题目位置 三、题目描述 给你一棵由 n 个顶点组成的无向树&#xff0c;顶点编号从 1 到 n。青蛙从 顶点 1 开始起跳。规则如下&#xff1a; 在一秒内&#xff0c;青蛙从它所在的当前顶点跳…