news 2026/8/28 8:09:13

一条消息的旅程:RabbitMQ 学习与实践(四)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一条消息的旅程:RabbitMQ 学习与实践(四)

专栏:RabbitMQ 进阶之路

个人主页:手握风云

目录

一、SpringBoot 整合 RabbitMQ

1.1. 环境准备

二、四大常用模式

2.1. Work Queue 工作队列模式

2.2. Publish/Subscribe 发布‑订阅

2.3. Routing 路由模式

2.4. Topics 通配符模式


一、SpringBoot 整合 RabbitMQ

1.1. 环境准备

核心依赖:

<dependencies> <!-- RabbitMQ整合核心依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webmvc-test</artifactId> <scope>test</scope> </dependency> </dependencies>

配置文件:

# 方式1:分字段配置 spring: rabbitmq: host: 公网 IP port: 5672 username: yang password: study virtual-host: test # 方式2:地址字符串简写 spring: rabbitmq: addresses: amqp://yang:study@公网 IP:5672/test

二、四大常用模式

2.1. Work Queue 工作队列模式

特点:同一个队列,多个消费者监听;一条消息只会被其中一个消费者消费,做任务分发。

  • 配置类声明队列
package com.yang.rabbitmqspringboot.config; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.core.*; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMQConfig { @Bean("workQueue") public Queue workQueue() { // 构建持久化队列 return QueueBuilder.durable(Constants.WORK_QUEUE).build(); } }
  • 生产者(Controller 发送消息)
package com.yang.rabbitmqspringboot.controller; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/producer") public class ProducerController { @Autowired private RabbitTemplate rabbitTemplate; @RequestMapping("/work") public String work() { // 向默认交换机发送 for (int i = 0; i < 10; i++) { rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE, "hello spring amqp: work..." + i); } return "发送成功"; } }
  • 消费者,两个方法监听同一个队列,形成竞争消费
package com.yang.rabbitmqspringboot.listener; import com.rabbitmq.client.Channel; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class WorkListener { @RabbitListener(queues = Constants.WORK_QUEUE) public void queueListener1(Message message, Channel channel) { System.out.println("Listener1 [" + Constants.WORK_QUEUE + "] 接收到消息" + message + ", channel: " + channel); } @RabbitListener(queues = Constants.WORK_QUEUE) public void queueListener2(Message message, Channel channel) { System.out.println("Listener2 [" + Constants.WORK_QUEUE + "] 接收到消息" + message + ", channel: " + channel); } }

2.2. Publish/Subscribe 发布‑订阅

特点:fanout 交换机,忽略 routingKey;消息复制多份,所有绑定该交换机的队列全部收到一模一样的消息。

  • Config 配置:声明 2 个队列 + Fanout 交换机 + 两个 Binding 绑定
@Bean("fanoutQueue1") public Queue fanoutQueue1() { return QueueBuilder.durable(Constants.FANOUT_QUEUE1).build(); } @Bean("fanoutQueue2") public Queue fanoutQueue2() { return QueueBuilder.durable(Constants.FANOUT_QUEUE2).build(); } @Bean("fanoutExchange") public FanoutExchange fanoutExchange() { return ExchangeBuilder.fanoutExchange(Constants.FANOUT_EXCHANGE).durable(true).build(); } @Bean("fanoutQueueBinding1") public Binding fanoutQueueBinding1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue1") Queue queue) { return BindingBuilder.bind(queue).to(fanoutExchange); } @Bean("fanoutQueueBinding2") public Binding fanoutQueueBinding2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue2") Queue queue) { return BindingBuilder.bind(queue).to(fanoutExchange); }
  • 生产者发送消息:routingKey 传空字符串
@RequestMapping("/fanout") public String fanout() { rabbitTemplate.convertAndSend(Constants.FANOUT_EXCHANGE, "", "hello spring amqp: fanout..."); return "发送成功"; }
  • 消费者:分别监听两个队列
package com.yang.rabbitmqspringboot.listener; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class FanoutListener { @RabbitListener(queues = Constants.FANOUT_QUEUE1) public void queueListener1(String message) { System.out.println("队列[" + Constants.FANOUT_QUEUE1 + "] 接收到消息:" + message); } @RabbitListener(queues = Constants.FANOUT_QUEUE2) public void queueListener2(String message) { System.out.println("队列[" + Constants.FANOUT_QUEUE2 + "] 接收到消息:" + message); } }

2.3. Routing 路由模式

特点:direct交换机;routingKey 必须和 Binding 绑定的 key 完全相等,队列才接收消息。适合日志分级等定向分发。

  • Config 配置
@Bean("directQueue1") public Queue directQueue1() { return QueueBuilder.durable(Constants.DIRECT_QUEUE1).build(); } @Bean("directQueue2") public Queue directQueue2() { return QueueBuilder.durable(Constants.DIRECT_QUEUE2).build(); } @Bean("directExchange") public DirectExchange directExchange() { return ExchangeBuilder.directExchange(Constants.DIRECT_EXCHANGE).durable(true).build(); } @Bean("directQueueBiding1") public Binding directQueueBiding1(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue1") Queue queue) { return BindingBuilder.bind(queue).to(directExchange).with("orange"); } @Bean("directQueueBiding2") public Binding directQueueBiding2(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) { return BindingBuilder.bind(queue).to(directExchange).with("black"); } @Bean("directQueueBiding3") public Binding directQueueBiding3(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) { return BindingBuilder.bind(queue).to(directExchange).with("orange"); }
  • 生产者,routingKey 动态传入
@RequestMapping("/direct/{routingKey}") public String direct(@PathVariable("routingKey") String routingKey) { rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE, routingKey, "hello spring amqp: direct..." + routingKey); return "发送成功"; }
  • 消费者监听两个队列
package com.yang.rabbitmqspringboot.listener; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class DirectListener { @RabbitListener(queues = Constants.DIRECT_QUEUE1) public void queueListener1(String message) { System.out.println("队列[" + Constants.DIRECT_QUEUE1 + "] 接收到消息:" + message); } @RabbitListener(queues = Constants.DIRECT_QUEUE2) public void queueListener2(String message) { System.out.println("队列[" + Constants.DIRECT_QUEUE2 + "] 接收到消息:" + message); } }

2.4. Topics 通配符模式

特点:topic交换机,支持通配符匹配。*:匹配一个单词(.分割);#:匹配0 个或者多个单词。

  • Config 配置
@Bean("topicQueue1") public Queue topicQueue1() { return QueueBuilder.durable(Constants.TOPIC_QUEUE1).build(); } @Bean("topicQueue2") public Queue topicQueue2() { return QueueBuilder.durable(Constants.TOPIC_QUEUE2).build(); } @Bean("topicExchange") public TopicExchange topicExchange() { return ExchangeBuilder.topicExchange(Constants.TOPIC_EXCHANGE).durable(true).build(); } @Bean("topicQueueBinding1") public Binding topicQueueBinding1(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue1") Queue queue) { return BindingBuilder.bind(queue).to(topicExchange).with("*.orange.*"); } @Bean("topicQueueBinding2") public Binding topicQueueBinding2(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){ return BindingBuilder.bind(queue).to(topicExchange).with("*.*.rabbit"); } @Bean("topicQueueBinding3") public Binding topicQueueBinding3(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){ return BindingBuilder.bind(queue).to(topicExchange).with("lazy.#"); }
  • 生产者
@RequestMapping("/topic/{routingKey}") public String topic(@PathVariable("routingKey") String routingKey) { rabbitTemplate.convertAndSend(Constants.TOPIC_EXCHANGE, routingKey, "hello spring amqp: topic..." + routingKey); return "发送成功"; }
  • 消费者
package com.yang.rabbitmqspringboot.listener; import com.yang.rabbitmqspringboot.constants.Constants; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class TopicListener { @RabbitListener(queues = Constants.TOPIC_QUEUE1) public void queueListener1(String message) { System.out.println("队列[" + Constants.TOPIC_QUEUE1 + "] 接收到消息:" + message); } @RabbitListener(queues = Constants.TOPIC_QUEUE2) public void queueListener2(String message) { System.out.println("队列[" + Constants.TOPIC_QUEUE2 + "] 接收到消息:" + message); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 8:08:11

低光增强实战:从基线到NTIRE Twilight Cowboy挑战的完整工程链路

图像增强赛道在近年计算机视觉挑战中热度很高&#xff0c;低光增强则是其中最能体现“从坏输入到好输出”的一类任务。NTIRE 2026 Low-light Enhancement 赛道以 “Twilight Cowboy Challenge” 为名&#xff0c;直接指向黄昏低照度、高动态范围、复杂光源混合的真实拍摄场景。…

作者头像 李华
网站建设 2026/8/28 8:04:52

学术论文写作全流程指南:从IMRaD结构到语言规范与修改策略

1. 从“写出来”到“写得好”&#xff1a;论文书写的核心价值 写论文&#xff0c;大概是每个学生和研究者都绕不开的“必修课”。很多人觉得&#xff0c;论文嘛&#xff0c;不就是把研究结果整理一下&#xff0c;按照格式要求填进去就行了吗&#xff1f;我最初也是这么想的&…

作者头像 李华
网站建设 2026/8/28 8:04:42

STM32定时器深度解析:从时钟树到PWM与输入捕获实战

1. 项目概述&#xff1a;为什么STM32的定时器是嵌入式开发的“心脏”&#xff1f; 如果你刚开始接触STM32&#xff0c;可能会觉得定时器&#xff08;Timer&#xff09;只是一个用来计时的简单外设&#xff0c;设置一个时间&#xff0c;让它到点触发个中断就完事了。但当你真正深…

作者头像 李华
网站建设 2026/8/28 8:04:06

Java项目练习题

购买两款披萨父类package com.lqy.test01; //父类&#xff1a;披萨 public class Pizza {//属性private String name;//名称private int size;//尺寸大小private int price;//价格//方法,为这三个属性提供set和get方法public String getName() {return name;}public void setN…

作者头像 李华
网站建设 2026/8/28 8:03:54

蓝桥杯Python真题解析:单词分析的高效解法与性能优化

1. 项目概述&#xff1a;从一道真题看蓝桥杯Python的考察脉络 今天我们来拆解蓝桥杯Python程序设计的一道经典真题——“单词分析”。这道题在历届比赛中出现频率不低&#xff0c;它看似简单&#xff0c;就是一个统计字符串中字母出现频率的问题&#xff0c;但恰恰是这种基础题…

作者头像 李华