SpringBoot整个RabbitMQ详细~
搭建环境
1、安装RabbitMQ,我是用的是Docker方式安装的,大家根据个人习惯自行安装哈
docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq -e RABBITMQ_DEFAULT_USER=qbb -e RABBITMQ_DEFAULT_PASS=qbb rabbitmq:3.8-management
SpringBoot整合RabbitMQ
Producer生产者端代码
1、创建一个maven工程

2、导入相关的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qbb</groupId>
<artifactId>springboot-rabbitmq</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
3、编写application.yml配置文件
server:
port: 9001
spring:
application:
name: springboot-rabbitmq
rabbitmq:
host: # 你MQ的地址
port: 5672
username: admin
password: admin
virtual-host: /
4、主启动类
package com.qbb.rabbitmq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 21:33
* @Description:
*/
@SpringBootApplication
public class SpringBootRabbitMQ {
public static void main(String[] args) {
SpringApplication.run(SpringBootRabbitMQ.class, args);
}
}
5、业务逻辑
(1)我们创建一个RabbitMQConfig的配置类,帮助我们来创建交换机、队列以及绑定关系
package com.qbb.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 21:34
* @Description:
*/
@Configuration
public class RabbitMQConfig {
/**
* 交换机名称
*/
public static final String TOPIC_EXCHANGE_NAME = "qiu_topic_exchange";
/**
* 队列名称
*/
public static final String QUEUE_NAME = "qiu_queue";
/**
* 创建交换机
*
* @return
*/
@Bean("qiuExchange")
public Exchange createExchange() {
return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_NAME).durable(true).build();
}
/**
* 创建队列
*
* @return
*/
@Bean("qiuQueue")
public Queue createQueue() {
return QueueBuilder.durable(QUEUE_NAME).build();
}
/**
* 绑定交换机和队列
*
* @param qiuExchange
* @param qiuQueue
* @return
*/
@Bean
public Binding binding(@Qualifier("qiuExchange") Exchange qiuExchange, @Qualifier("qiuQueue") Queue qiuQueue) {
return BindingBuilder.bind(qiuQueue).to(qiuExchange).with("qiu.#").noargs();
}
}
(2)编写Producer发送消息的测试代码
package com.qbb.rabbitmq;
import com.qbb.rabbitmq.config.RabbitMQConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 21:56
* @Description:
*/
@SpringBootTest
public class ProducerTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSendMsg(){
rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_EXCHANGE_NAME,
"qiu.haha", "等我完成目标就来找你~");
}
}


Consumer消费者端代码
1、创建一个maven工程

2、导入相关的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qbb</groupId>
<artifactId>springboot-rabbitmq-consumer</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
3、编写application.yml配置文件
server:
port: 9002
spring:
application:
name: springboot-rabbitmq
rabbitmq:
host:
port: 5672
username: admin
password: admin
virtual-host: /
4、主启动类
package com.qbb.rabbitmq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 22:09
* @Description:
*/
@SpringBootApplication
public class SpringBootRabbitMQConsumer {
public static void main(String[] args) {
SpringApplication.run(SpringBootRabbitMQConsumer.class, args);
}
}
5、业务逻辑
(1)创建一个MQListener监听器,用于监听队列消费消息
package com.qbb.rabbitmq.listener;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 22:10
* @Description:
*/
@Component
public class RabbitMQListener {
/**
* 监听队列
*
* @param message
*/
@RabbitListener(queues = "qiu_queue")
public void msgConsumer(Message message) {
System.out.println("message = " + message);
}
}
(2)启动主程序测试一下

RabbitMQ高级特性

1、消息可靠性投递confirm确认模式和return回退模式
- 修改yml配置文件
spring:
application:
name: springboot-rabbitmq
rabbitmq:
host:
port: 5672
username: admin
password: admin
virtual-host: /
# 是否触发回调方法
# NONE值是禁用发布确认模式,是默认值
# CORRELATED值是发布消息成功到交换器后会触发回调方法
# SIMPLE值经测试有两种效果:
# 其一效果和CORRELATED值一样会触发回调方法
# 其二在发布消息成功后使用rabbitTemplate
# 调用waitForConfirms或waitForConfirmsOrDie方法等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,
# 要注意的点是waitForConfirmsOrDie方法如果返回false则会关闭channel,则接下来无法发送消息到broker;
publisher-confirm-type: correlated
publisher-returns: true
listener:
simple:
# 开启手动确定
acknowledge-mode: manual
- 编写测试代码
package com.qbb.rabbitmq;
import com.qbb.rabbitmq.config.RabbitMQConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-28 21:56
* @Description:
*/
@SpringBootTest
public class ProducerTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSendMsg(){
/**
* false:RabbitMQ会把消息直接丢弃
* true:RabbitMQ会调用Basic.Return命令将消息返回给生产者
*/
rabbitTemplate.setMandatory(true);
//设置ReturnsCallback
rabbitTemplate.setReturnsCallback( returnedMessage -> {
//消息对象
Message message = returnedMessage.getMessage();
//错误码
int replyCode = returnedMessage.getReplyCode();
//错误信息
String replyText = returnedMessage.getReplyText();
//交换机
String exchange = returnedMessage.getExchange();
//路由key
String routingKey = returnedMessage.getRoutingKey();
System.out.println("消息从交换机到队列失败,详细信息如下:");
System.out.println("消息对象:"+message);
System.out.println("错误码:"+replyCode);
System.out.println("错误信息:"+replyText);
System.out.println("交换机:"+exchange);
System.out.println("路由key:"+routingKey);
});
//设置ConfirmCallback
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
/**
* @param correlationData 相关配置信息
* @param ack 交换机是否成功收到消息
* @param cause 错误信息
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack){
System.out.println("成功发送消息到交换机");
}else {
System.out.println("消息发送到交换机失败");
System.out.println("失败原因:"+cause);
}
}
});
// 错误的示例,大家自行修改
rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_EXCHANGE_NAME,
"qiu.haha", "等我完成目标就来找你~");
}
}
2、Consumer端手动ACK
RabbitMQ提供了三种确认方式:
- 自动确认:acknowledge="none"
- 手动确认:acknowledge="manual"
- 根据异常情况确认:acknowledge="auto" (不推荐)
修改配置文件
listener:
type: simple
simple:
#采用手动应答
acknowledge-mode: manual
prefetch: 1 #限制每次发送一条数据。
添加一个ACKListener监听器
package com.qbb.rabbitmq.listener;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-07-29 21:32
* @Description:
*/
@Component
public class AckListener {
@RabbitListener(queues = {"akc-queue"})
public void testQueue(Message message, Channel channel) throws IOException {
System.out.println("ack-queue消费:" + new String(message.getBody()));
/*
listener:
type: simple
simple:
#采用手动应答
acknowledge-mode: manual
prefetch: 1 #限制每次发送一条数据。
*/
// 采用手动ack,一条条的消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
/**
* 参数一:DeliveryTag
* 参数二:是否接收多个消息
* 参数三:是否重回队列,如果为true消息会重新回到queue, broker会重新发送该消息给消费端
*/
//channel.basicNack(message.getMessageProperties().getDeliveryTag(),true,true);
}
}
测试

3、Consumer端限流
修改配置文件
#采用手动应答
acknowledge-mode: manual
prefetch: 1 #限制每次消费N条数据。
4、TTL
- 设置队列的过期时间
- x-message-ttl,单位:ms(毫秒),这样的话进入队列的所有消息都遵循这个过期时间。
- 设置单个消息的过期时间(expiretion)
- expiration,单位:ms(毫秒),这样的话只有这条消息有过期时间。这里的消息过期了,如果这条消息是在头部,才会丢弃
5、死信队列
- 消息成为死信的三种情况
- 消息超过了队列的最大长度(max-length)
- Consumer端basicNAck|basicReject,消费端拒收,并且requeue=false不重新入队
- 消息过期
6、延迟队列(RabbitMQ没有这个实现)
- 但是我们可以通过TTL+死信队列解决

7、日志与监控
http://ip:15672/直接访问web图形化界面,用命令也可以查看,但是个人感觉没有图形化界面友好!!!
8、保证消息的幂等性
- 使用乐观锁的方式解决
SpringBoot整个RabbitMQ详细~的更多相关文章
- Springboot接入RabbitMQ详细教程
本文适用于对 RabbitMQ 有所了解的人,在此不讨论MQ的原理,只讨论如何接入.其实Spring Boot 集成 RabbitMQ 非常简单,本文章使用的是Spring Boot 提供了sprin ...
- 功能:SpringBoot整合rabbitmq,长篇幅超详细
SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...
- SpringBoot集成RabbitMQ
官方说明:http://www.rabbitmq.com/getstarted.html 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ ...
- rabbitmq学习(五):springboot整合rabbitmq
一.Springboot对rabbitmq的支持 springboot提供了对rabbitmq的支持,并且大大简化了rabbitmq的相关配置.在springboot中,框架帮我们将不同的交换机划分出 ...
- SpringBoot 整合 RabbitMQ(包含三种消息确认机制以及消费端限流)
目录 说明 生产端 消费端 说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同 ...
- Springboot 整合RabbitMq ,用心看完这一篇就够了
该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...
- RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)
1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...
- SpringBoot整合RabbitMQ实现六种工作模式
RabbitMQ主要有六种种工作模式,本文整合SpringBoot分别介绍工作模式的实现. 前提概念 生产者 消息生产者或者发送者,使用P表示: 队列 消息从生产端发送到消费端,一定要通过队列转发,使 ...
- SpringBoot集成rabbitmq(二)
前言 在使用rabbitmq时,我们可以通过消息持久化来解决服务器因异常崩溃而造成的消息丢失.除此之外,我们还会遇到一个问题,当消息生产者发消息发送出去后,消息到底有没有正确到达服务器呢?如果不进行特 ...
- SpringBoot之RabbitMQ的使用
一 .RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件,消息中间件的工作过程可以用生产者消费者模型来表示.即,生产者不断的向消息队列发 ...
随机推荐
- 在编写API接口的技术文章时应注意的内容
编写API接口的技术文章时,建议包含以下内容: 1. 简介:介绍API接口的目的和作用,以及所属的项目或服务. 2. 接口描述:详细描述API接口的功能和使用方法,包括输入参数.输出结果和可能的错误码 ...
- 每天一道面试题:Spring的Bean生命周期
Spring的Bean生命周期包括以下步骤: 1.实例化(Instantiation):当Spring容器接收到创建Bean的请求时,它会先实例化Bean对象.这个过程可以通过构造函数.工厂方法或者反 ...
- oracle导入导出某个schema数据
背景 公司之前部门拆分,但一些服务并没有拆分清楚.其中一个老服务,两个部门都在用,现在为了避免互相影响,决定克隆该服务.克隆就要克隆全套,当然也包括数据库,我们这个老服务,用的oracle,所以,就涉 ...
- Longest Divisors Interval
Smiling & Weeping ----总有一个人, 一直住在心底, 却消失在生活里. Given a positive integer n, find the maximum size ...
- 对称加密 vs 非对称加密
计算机网络在给我们带来便利的同时,也存在很多安全隐患,比如信息伪造,病毒入侵,端点监听,SQL 注入等,给我们日常生活造成很严重的影响. 那么这篇文章我就跟大家聊聊常见的网络安全隐患,只作为科普,不能 ...
- Windows上Dart安装
过程 *1 去github上下载一个release包或者直接将flutter通过git clone下来 *2 将下载下来的flutter/bin添加到path中 *3 此时运行flutter或者flu ...
- 「codeforces - 868F」Yet Another Minimization Problem
link. 值域分治优化决策单调性 DP 的 trick.朴素做法 trivial,不赘述. 考虑求取一个区间 \([l,r]\) 的 DP 值.先搞定在 \(m=\lfloor\frac{l+r}{ ...
- 记一次 .NET 某餐饮小程序 内存暴涨分析
一:背景 1. 讲故事 前些天有位朋友找到我,说他的程序内存异常高,用 vs诊断工具 加载时间又太久,让我帮忙看一下到底咋回事,截图如下: 确实,如果dump文件超过 10G 之后,市面上那些可视化工 ...
- Arduino基础入门之三按键开关
目的:通过读取按键开关的信号,实现其他器件的控制 难点:下拉电阻和上拉电阻 一.关于按键开关 按键开关如上图[1]所示,但我拿到实物,最令我头疼的是按钮下边4个角,我不知那两边是相通的(就是和图中12 ...
- VideoCapture
from xgoedu import XGOEDU import time #实例化edu XGO_edu = XGOEDU() XGO_edu.lcd_text(50,50,'hello',colo ...