Spring Boot 整合 RabbitMQ:手动 ACK 与 QoS 配置详解

在分布式系统中,消息队列(Message Queue)是实现异步通信的重要组件。RabbitMQ 作为一个功能强大的消息代理,提供了多种消息传递模式和丰富的配置选项。在生产环境中,为了确保消息的可靠传递,我们通常需要配置手动确认(Manual Acknowledgment)和消息预取(QoS)。

本文将详细介绍如何在 Spring Boot 项目中通过 application.properties 配置文件来配置 RabbitMQ 的手动 ACK 和 QoS,并通过实际代码示例帮助你理解这些配置的作用和使用场景。

1. 手动 ACK 与 QoS 的概念

1.1 手动 ACK(Manual Acknowledgment)

在 RabbitMQ 中,消费者在接收到消息后,默认会自动确认(Auto Acknowledgment)消息。这种方式虽然简单,但在某些场景下可能会导致消息丢失或重复消费。例如,如果消费者在处理消息时发生异常,消息可能会被错误地确认,导致消息丢失。

手动确认机制允许消费者在处理完消息后,手动向 RabbitMQ 发送确认信号。这种方式可以确保消息只有在被成功处理后才会被确认,从而提高消息的可靠性。

1.2 QoS(Quality of Service)

QoS 配置用于控制消费者从 RabbitMQ 中预取消息的数量。默认情况下,RabbitMQ 会将所有消息一次性推送给消费者,这可能会导致消费者处理不过来,甚至导致内存溢出。

通过配置 QoS,我们可以限制消费者一次从 RabbitMQ 中预取的消息数量,从而避免消息堆积和资源浪费。

2. Spring Boot 整合 RabbitMQ 配置

2.1 环境准备

在开始之前,请确保你已经安装了以下环境:

  • Java 8 或更高版本
  • Maven 或 Gradle
  • RabbitMQ 服务器(可以通过 Docker 快速启动)

你可以通过以下命令使用 Docker 启动 RabbitMQ 服务器:

docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

启动后,可以通过 http://localhost:15672 访问 RabbitMQ 的管理界面,默认用户名和密码为 guest/guest

2.2 创建 Spring Boot 项目

你可以通过 Spring Initializr 快速创建一个 Spring Boot 项目。选择以下依赖:

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

生成项目后,导入到你的 IDE 中。

2.3 配置 RabbitMQ

application.properties 文件中添加 RabbitMQ 的配置:

# RabbitMQ 配置
spring.rabbitmq.host=192.168.200.142
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/test
spring.rabbitmq.username=test
spring.rabbitmq.password=test

# 消费者配置
# 设置手动 ACK
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# 设置 QoS,每次预取 1 条消息
spring.rabbitmq.listener.simple.prefetch=1
# 设置并发消费者数量
spring.rabbitmq.listener.simple.concurrency=3
# 设置最大并发消费者数量
spring.rabbitmq.listener.simple.max-concurrency=10

2.4 定义消息队列和交换机

在 Spring Boot 中,我们可以通过 @Bean 注解来定义 RabbitMQ 的队列、交换机和绑定关系。

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    public static final String QUEUE_NAME = "spring-boot-queue";
    public static final String EXCHANGE_NAME = "spring-boot-exchange";
    public static final String ROUTING_KEY = "spring-boot-routing-key";

    @Bean
    public Queue queue() {
        return new Queue(QUEUE_NAME, true); // 设置队列为持久化
    }

    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(EXCHANGE_NAME);
    }

    @Bean
    public Binding binding(Queue queue, TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);
    }
}

2.5 发送消息

在 Spring Boot 中,我们可以通过 RabbitTemplate 来发送消息。

import com.allen.config.RabbitMQConfig;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MessageController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/send")
    public String sendMessage(@RequestParam String message) {
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, RabbitMQConfig.ROUTING_KEY, message);
        return "Message sent: " + message;
    }
}

2.6 接收消息并手动 ACK

通过 @RabbitListener 注解,我们可以监听指定的队列并处理接收到的消息。在手动 ACK 模式下,我们需要手动确认消息。

import com.allen.config.RabbitMQConfig;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class MessageListener {

    @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
        try {
            System.out.println("Received message: " + message);
            // 模拟业务处理
            Thread.sleep(1000);
            channel.basicAck(deliveryTag, false); // 手动确认消息
        } catch (Exception e) {
            channel.basicNack(deliveryTag, false, true); // 拒绝消息并重新入队
        }
    }
}

2.8 测试

启动 Spring Boot 应用,访问 http://localhost:8080/send?message=HelloRabbitMQ,你将在控制台看到如下输出:

Received message: HelloRabbitMQ

此时,消息已经被成功接收并手动确认。

三、总结

本文详细介绍了如何在 Spring Boot 项目中配置 RabbitMQ 的手动 ACK 和 QoS。通过手动 ACK,我们可以确保消息只有在被成功处理后才会被确认,从而提高消息的可靠性。通过 QoS 配置,我们可以控制消费者预取消息的数量,避免消息堆积和资源浪费。

在实际项目中,手动 ACK 和 QoS 是确保消息队列系统稳定性和可靠性的重要配置。希望本文对你在 Spring Boot 和 RabbitMQ 的学习与实践中有所帮助!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字化审计咨询服务,企业转型数字化审计的必要条件

人工智能、云计算、大数据、物联网等新兴技术的快速发展&#xff0c;为企业的数字化转型提供了强大的技术支持。这些技术逐渐被应用到企业运营管理的方方面面&#xff0c;推动了企业内部审计工作的变革。随着数字化转型的深化和信息技术的不断发展&#xff0c;数字化审计将成为…

【QT常用技术讲解】发送POST包(两种方式:阻塞方式及非阻塞方式)

前言 http/https(应用层)协议是广泛使用的网络通信协议。在很多与第三方API对接的场景中&#xff0c;通常是通过http/https协议完成&#xff0c;比如API对接时&#xff0c;通常要通过POST包获取access_token进行鉴权&#xff0c;然后再进行数据交互&#xff08;本篇也包含有对接…

重撸设计模式--代理模式

文章目录 定义UML图代理模式主要有以下几种常见类型&#xff1a;代理模式涉及的主要角色有&#xff1a;C 代码示例 定义 代理模式&#xff08;Proxy Pattern&#xff09;属于结构型设计模式&#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。 通过引入代理对象&am…

【Steel Code】 10.5 COMPOSITE COLUMNS

10.5 COMPOSITE COLUMNS 组合柱 10.5.1 General 总则 (1) This clause applies for the design of composite columns and composite compression members with fully encased H sections, partially encased H sections, and infilled rectangular and circular hollow sect…

11.vector的介绍及模拟实现

1.vector的介绍 记得之前我们用C语言实现过顺序表&#xff0c;vector本质上也是顺序表&#xff0c;一个能够动态增长的数组。 vector 的底层实现机制 - 动态数组&#xff1a;vector 的底层实现是动态数组。它在内存中连续存储元素&#xff0c;就像一个可以自动调整大小的数…

封装(2)

大家好&#xff0c;今天我们来介绍一下包的概念&#xff0c;知道包的作用可以更好的面对今后的开发&#xff0c;那么我们就来看看包是什么东西吧。 6.3封装扩展之包 6.3.1包的概念 在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组…

go官方日志库带色彩格式化

go默认的 log 输出的日志样式比较难看&#xff0c;所以通过以下方式进行了美化和格式化&#xff0c;而且加入了 unicode 的ascii码&#xff0c;进行色彩渲染。 package mainimport ("fmt""log""os""runtime""strings""…

0基础学前端系列 -- 深入理解 HTML 布局

在现代网页设计中&#xff0c;布局是至关重要的一环。良好的布局不仅能提升用户体验&#xff0c;还能使内容更具可读性和美观性。HTML&#xff08;超文本标记语言&#xff09;结合 CSS&#xff08;层叠样式表&#xff09;为我们提供了多种布局方式。本文将详细介绍流式布局、Fl…

Windows开启IIS后依然出现http error 503.the service is unavailable

问题背景 已启用IIS服务&#xff0c;配置步骤可以参考Windows10 IIS Web服务器安装配置 问题描述 在这一步浏览网站时&#xff0c;并没有出现默认首页&#xff0c;而是 http error 503 the service is unavailable 问题解决 参考 成功解决http error 503.the service is un…

BuildCTF 公开赛web部分wp

文章目录 LovePopChainRedFlagWhy_so_serials?babyuploadeazyl0ginez!httpez_md5find-the-idsubtflock刮刮乐我写的网站被rce了&#xff1f; LovePopChain payload: <?php class MyObject{public $NoLove"Do_You_Want_Fl4g?";public $Forgzy;public functi…

diff 算法实现的几种方法和前端中的应用

diff 算法原理和几种实现方法 diff 是什么 diff 算法就是比较两个数据的差异&#xff0c;例如字符串的差异&#xff0c;对象的差异。 常用于版本管理&#xff08;git&#xff09;例如下面的实际案例。 github 上某个 commit&#xff0c;旧代码和新代码之间的不同 diff 展示…

Nacos源码搭建

拉取并配置代码 仓库地址 https://github.com/alibaba/nacos找到config 模块中找到 \resources\META-INF\mysql-schema.sql&#xff0c;在本地mysql中创建数据库nacos-config&#xff0c;将该脚本导入执行创建表。 找到console模块下的配置文件application.properties&#x…

C# Winfrom chart图 实例练习

代码太多了我就不展示了&#xff0c;贴一些比较有代表性的 成品效果展示&#xff1a; Excel转Chart示例 简单说一下我的思路 \ 先把Excel数据展示在dataGridView控件上 XLIST 为 X轴的数据 XLIST 为 Y轴的数据 ZLIST 为 展示的数据进行数据处理点击展示即可 // 将Excel数…

# 起步专用 - 哔哩哔哩全模块超还原设计!(内含接口文档、数据库设计)

↑ 上方下载文档 (大小374KB) 接口文档预览 (超过50个接口) 一、数据库25张表er-关系清晰构图&#xff01;(tip: 鼠标右键图片 > 放大图像) 二、难点/经验 详细说明 热门评论排序评论点赞列表|DTO封装经验分享|精华接口文档说明 组员都说喜欢分档对应枚举码 如果这篇文章…

【Go学习】从一个出core实战问题看Go interface赋值过程

0x01 背景 版本中一个同学找我讨论一个服务出core的问题&#xff0c;最终他靠自己的探索解决了问题&#xff0c;给出了初步的直接原因结论&#xff0c;"Go 中 struct 赋值不是原子的”。间接原因的分析是准确的&#xff0c;直接原因&#xff0c;我有点怀疑。当时写了一些…

leetcode之hot100---54螺旋矩阵(C++)

思路一&#xff1a;模拟 模拟螺旋矩阵的路径&#xff0c;路径超出界限&#xff0c;顺时针旋转&#xff0c;使用一个数组记录当前数字是否被访问到&#xff0c;直到所有的数字全部被访问 class Solution {//一个静态的常量数组&#xff0c;用于标记螺旋矩阵的移动方向(行列变化…

新能源汽车锂离子电池各参数的时间序列关系

Hi&#xff0c;大家好&#xff0c;我是半亩花海。为了进一步开展新能源汽车锂离子电池的相关研究&#xff0c;本文主要汇总并介绍了电动汽车的锂离子电池的各项参数&#xff0c;通过 MATLAB 软件对 Oxford Dataset 的相关数据集进行数据处理与分析&#xff0c;进一步研究各项参…

FastStone 10.x 注册码

简介 FastStone Capture是一款经典好用的屏幕截图软件&#xff0c;在屏幕截图领域具有广泛的应用和众多优势。 软件基本信息 FastStone Capture体积小巧&#xff0c;占用内存少&#xff0c;这使得它在运行时不会给计算机系统带来过多的负担&#xff0c;即使在配置较低的电脑…

AI合成图片是什么意思?有什么用?

随着人工智能的发展&#xff0c;现在市面上出现了很多对企业帮助很大的AI工具&#xff0c;比如说AI合成图片、AI换模特、AI穿衣、AI图片设计等等&#xff0c;下面小编就以AI合成图片为例&#xff0c;为大家详细介绍下。 一、AI合成图片是什么意思? AI合成图片主要就是指利用人…

【示例】Vue AntV G6 base64自定义img 动画效果,自适应宽高屏

需求&#xff1a;拓扑图中需要用动画的线条连接node&#xff0c;在此之前将HTML页面改成了vue页面。需要使用到G6的registerEdge 自定义边&#xff0c;小车的图片需要转成base64格式&#xff08;并翻转&#xff09;&#xff0c;可以通过base64转image查看原来的样子。 另外&am…