搭建环境

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详细~的更多相关文章

  1. Springboot接入RabbitMQ详细教程

    本文适用于对 RabbitMQ 有所了解的人,在此不讨论MQ的原理,只讨论如何接入.其实Spring Boot 集成 RabbitMQ 非常简单,本文章使用的是Spring Boot 提供了sprin ...

  2. 功能:SpringBoot整合rabbitmq,长篇幅超详细

    SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...

  3. SpringBoot集成RabbitMQ

    官方说明:http://www.rabbitmq.com/getstarted.html 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ ...

  4. rabbitmq学习(五):springboot整合rabbitmq

    一.Springboot对rabbitmq的支持 springboot提供了对rabbitmq的支持,并且大大简化了rabbitmq的相关配置.在springboot中,框架帮我们将不同的交换机划分出 ...

  5. SpringBoot 整合 RabbitMQ(包含三种消息确认机制以及消费端限流)

    目录 说明 生产端 消费端 说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同 ...

  6. Springboot 整合RabbitMq ,用心看完这一篇就够了

    该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...

  7. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  8. SpringBoot整合RabbitMQ实现六种工作模式

    RabbitMQ主要有六种种工作模式,本文整合SpringBoot分别介绍工作模式的实现. 前提概念 生产者 消息生产者或者发送者,使用P表示: 队列 消息从生产端发送到消费端,一定要通过队列转发,使 ...

  9. SpringBoot集成rabbitmq(二)

    前言 在使用rabbitmq时,我们可以通过消息持久化来解决服务器因异常崩溃而造成的消息丢失.除此之外,我们还会遇到一个问题,当消息生产者发消息发送出去后,消息到底有没有正确到达服务器呢?如果不进行特 ...

  10. SpringBoot之RabbitMQ的使用

    一 .RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件,消息中间件的工作过程可以用生产者消费者模型来表示.即,生产者不断的向消息队列发 ...

随机推荐

  1. 如何使用关键词搜索API接口获取到快手的商品

    如果您想使用关键词搜索API接口获取到快手的商品,可以通过以下步骤实现: 1. 首先注册账号.根据文档申请相应的接口权限. 2. 确定需要使用的API接口.对于商品搜索,您可以查看相关的API文档以获 ...

  2. prometheus 监控实战篇

    prometheus 监控 目录 prometheus 监控 1.上传tar包 2.解压到对应文件夹 3.配置开机自启动 4.配置Prometheus 5.black_exporter 监控网站状态 ...

  3. [python] 在ubuntu中, 如何运行指定位置的py程序

    首先打开终端 Ctrl + Alt + T 运行py程序 进入py文件所在目录 (例如: cd 桌面) 运行py程序: python a.py

  4. KMP字符串对比算法及next数组计算

    (注:该贴主要运用python实现该算法) 先谈谈KMP算法吧.KMP算法的全称是Knuth-Morris-Pratt 算法,它是用来进行字符串查找,即在某个主字符串里面找到某个特定子字符串.但是好像 ...

  5. Q-REG论文阅读

    Q-REG Jin, S., Barath, D., Pollefeys, M., & Armeni, I. (2023). Q-REG: End-to-End Trainable Point ...

  6. MySQL中sql_mode的设置

    在升级MySQL版本到8.0的过程中,需要关注sql_mode参数默认值的变化,8.0版本sql_mode不支持 NO_AUTO_CREATE_USER,要避免配置的sql_mode中带有 NO_AU ...

  7. React跨路由组件动画

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:佳岚 回顾传统React动画 对于普通的 React 动画 ...

  8. 数据结构与算法 | 链表(Linked List)

    链表(Linked List)是一种线性数据结构,它由一系列节点(Node)组成,每个节点包含两部分:数据和指向下(上)一个节点的引用(或指针).链表中的节点按照线性顺序连接在一起(相邻节点不需要存储 ...

  9. 【Unity3D】UI Toolkit样式选择器

    1 前言 ​ UI Toolkit简介 中介绍了样式属性,UI Toolkit容器 和 UI Toolkit元素 中介绍了容器和元素,本文将介绍样式选择器(Selector),主要包含样式类选择器(C ...

  10. 宏任务和微任务,同步异步,promis,await执行顺序

    本文作为EVENLOOP事件循环的延伸: 执行顺序: ------------循环---------- |                                              | ...