SpringBoot 整合 RabbitMQ:和这只“兔子”交朋友

简介: RabbitMQ 就像是一个超级邮差兔,不过它不送胡萝卜,专门传递消息!交换机(Exchange),队列(Queue),路由键(Routing Key),消息(Message)。

大家好,我是小悟。

第一章:认识 RabbitMQ —— 不是普通的兔子!

RabbitMQ 就像是一个超级邮差兔,不过它不送胡萝卜,专门传递消息!想象一下:

  • 🏢 交换机(Exchange):邮局的分拣中心,负责把信件分到正确的路线
  • 📮 队列(Queue:你的专属邮箱,消息就在这里等你来取
  • 🏷️ 路由键(Routing Key:信封上的地址标签
  • 📦 消息(Message):你要传递的包裹(可以是任何数据)

这只“兔子”有四种工作模式:

  1. Hello World 模式:简单直接,像扔飞盘一样
  2. Work Queues 模式:多个工人抢活干,卷起来了!
  3. Publish/Subscribe 模式:广播模式,一人说话全村听见
  4. Routing & Topics 模式:智能分发,精准投喂

第二章:搭建“胡萝卜农场” —— 环境准备

2.1 安装 RabbitMQ

# 用 Docker 快速召唤兔子
docker run -d \
  --name rabbitmq \
  -p 5672:5672 \
  -p 15672:15672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=admin123 \
  rabbitmq:management
# 访问管理界面:http://localhost:15672
# 账号:admin / 密码:admin123

2.2 创建 SpringBoot 项目

<!-- pom.xml 添加“兔粮” -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

第三章:配置“兔子窝” —— 连接设置

# application.yml
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: admin123
    # 虚拟主机,相当于兔子的公寓号
    virtual-host: /
    # 开启消息确认(确保兔子没偷吃消息)
    publisher-confirm-type: correlated
    publisher-returns: true
    listener:
      simple:
        # 手动确认消息(收到要说谢谢哦)
        acknowledge-mode: manual
        # 并发消费者数量(几只兔子一起干活)
        concurrency: 3
        max-concurrency: 10

第四章:定义“胡萝卜传输协议” —— 配置类

@Configuration
public class RabbitConfig {
    
    // 定义一个队列 - 就像给兔子一个收件箱
    @Bean
    public Queue carrotQueue() {
        // durable: true 表示兔子重启后队列还在(持久化)
        return new Queue("carrot.queue", true);
    }
    
    // 再定义一个队列,用来放烂掉的胡萝卜
    @Bean
    public Queue deadCarrotQueue() {
        return new Queue("dead.carrot.queue", true);
    }
    
    // 定义一个直连交换机 - 最简单的邮局
    @Bean
    public DirectExchange carrotExchange() {
        return new DirectExchange("carrot.exchange", true, false);
    }
    
    // 绑定队列和交换机(告诉兔子哪个邮箱放哪条路)
    @Bean
    public Binding bindCarrot() {
        return BindingBuilder.bind(carrotQueue())
                .to(carrotExchange())
                .with("carrot.routing.key"); // 路由键
    }
    
    // JSON 消息转换器(把胡萝卜包装成标准快递盒)
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
    
    // 死信队列配置(处理那些没人要的胡萝卜)
    @Bean
    public Queue carrotQueueWithDLX() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", "dead.letter.exchange");
        args.put("x-dead-letter-routing-key", "dead.carrot");
        return new Queue("carrot.with.dlx", true, false, false, args);
    }
}

第五章:“种胡萝卜” —— 生产者代码

@Component
@Slf4j
public class CarrotProducer {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    /**
     * 发送一根普通胡萝卜
     */
    public void sendFreshCarrot(String message) {
        log.info("发射一根新鲜胡萝卜: {}", message);
        
        // 确保消息持久化(放冰箱保存)
        MessageProperties props = MessagePropertiesBuilder.newInstance()
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .build();
        
        Message msg = new Message(message.getBytes(), props);
        
        rabbitTemplate.convertAndSend(
            "carrot.exchange",
            "carrot.routing.key",
            msg,
            new CorrelationData(UUID.randomUUID().toString())
        );
        
        log.info("胡萝卜已交给兔子快递员");
    }
    
    /**
     * 发送一根 JSON 格式的豪华胡萝卜
     */
    public void sendLuxuryCarrot(CarrotDTO carrot) {
        log.info("准备发送豪华胡萝卜: {}", carrot);
        
        // 设置回调(确认兔子收到没)
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("兔子确认收到豪华胡萝卜,ID: {}", correlationData.getId());
            } else {
                log.error("兔子拒收豪华胡萝卜!原因: {}", cause);
            }
        });
        
        rabbitTemplate.convertAndSend(
            "carrot.exchange",
            "carrot.routing.key",
            carrot
        );
    }
    
    /**
     * 发送延迟胡萝卜(10秒后才送达)
     */
    public void sendDelayedCarrot(String message, int delaySeconds) {
        log.info("设置延迟胡萝卜,{}秒后送达: {}", delaySeconds, message);
        
        rabbitTemplate.convertAndSend(
            "delay.exchange",
            "delay.key",
            message,
            msg -> {
                msg.getMessageProperties().setDelay(delaySeconds * 1000);
                return msg;
            }
        );
    }
}
// 胡萝卜数据传输对象
@Data
@AllArgsConstructor
@NoArgsConstructor
class CarrotDTO {
    private String color;
    private Integer weight;
    private Date harvestTime;
    private List<String> vitamins;
}

第六章:“吃胡萝卜” —— 消费者代码

@Component
@Slf4j
public class CarrotConsumer {
    
    /**
     * 处理新鲜胡萝卜 - 自动确认版
     */
    @RabbitListener(queues = "carrot.queue")
    public void eatFreshCarrot(String message) {
        log.info("兔子正在啃胡萝卜: {}", message);
        // 模拟吃胡萝卜的过程
        try {
            Thread.sleep(1000);
            log.info("真香!胡萝卜吃完了");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 处理豪华胡萝卜 - 手动确认版
     */
    @RabbitListener(queues = "luxury.carrot.queue")
    public void eatLuxuryCarrot(Message message, Channel channel, 
                               @Payload CarrotDTO carrot) {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        
        try {
            log.info("收到豪华胡萝卜!颜色: {}, 重量: {}g", 
                    carrot.getColor(), carrot.getWeight());
            
            // 模拟复杂的处理逻辑
            processLuxuryCarrot(carrot);
            
            // 手动确认(告诉兔子:我吃完了,你可以送下一个了)
            channel.basicAck(deliveryTag, false);
            log.info("豪华胡萝卜处理完成,已确认");
            
        } catch (Exception e) {
            log.error("吃豪华胡萝卜时噎住了: {}", e.getMessage());
            
            try {
                // 处理失败,拒绝消息(可以设置重新入队或丢弃)
                channel.basicNack(deliveryTag, false, true); // 重新入队
                // channel.basicReject(deliveryTag, false); // 直接丢弃
            } catch (IOException ioException) {
                log.error("无法拒绝消息: {}", ioException.getMessage());
            }
        }
    }
    
    /**
     * 批量吃胡萝卜(提高效率)
     */
    @RabbitListener(queues = "batch.carrot.queue", 
                   containerFactory = "batchFactory")
    public void eatBatchCarrot(List<Message> messages, Channel channel) {
        log.info("收到一批胡萝卜,共{}根", messages.size());
        
        for (Message message : messages) {
            try {
                String carrot = new String(message.getBody());
                log.info("正在处理胡萝卜: {}", carrot);
                // 批量确认
                channel.basicAck(message.getMessageProperties()
                    .getDeliveryTag(), false);
            } catch (Exception e) {
                log.error("处理失败: {}", e.getMessage());
            }
        }
    }
    
    private void processLuxuryCarrot(CarrotDTO carrot) {
        // 复杂的业务逻辑
        log.info("分析胡萝卜营养成分...");
        log.info("维生素含量: {}", carrot.getVitamins());
        // 这里可以添加数据库操作、调用其他服务等
    }
}

第七章:特殊场景处理

7.1 死信队列配置

@Configuration
public class DeadLetterConfig {
    
    @Bean
    public DirectExchange deadLetterExchange() {
        return new DirectExchange("dead.letter.exchange");
    }
    
    @Bean
    public Queue deadLetterQueue() {
        return new Queue("dead.letter.queue");
    }
    
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue())
                .to(deadLetterExchange())
                .with("dead.carrot");
    }
    
    /**
     * 监听死信队列
     */
    @Component
    @Slf4j
    public class DeadLetterConsumer {
        @RabbitListener(queues = "dead.letter.queue")
        public void handleDeadLetter(String message) {
            log.warn("收到死信胡萝卜,需要人工处理: {}", message);
            // 可以发送告警邮件、记录日志等
        }
    }
}

7.2 延迟队列(定时任务)

@Configuration
public class DelayConfig {
    
    @Bean
    public CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("delay.exchange", 
                "x-delayed-message", true, false, args);
    }
    
    @Bean
    public Queue delayQueue() {
        return new Queue("delay.queue");
    }
    
    @Bean
    public Binding delayBinding() {
        return BindingBuilder.bind(delayQueue())
                .to(delayExchange())
                .with("delay.key")
                .noargs();
    }
}

第八章:测试我们的“兔子农场”

@SpringBootTest
@Slf4j
class RabbitmqTest {
    
    @Autowired
    private CarrotProducer carrotProducer;
    
    @Test
    void testSendCarrot() {
        // 测试发送普通胡萝卜
        carrotProducer.sendFreshCarrot("我是新鲜的胡萝卜!");
        
        // 测试发送豪华胡萝卜
        CarrotDTO luxuryCarrot = new CarrotDTO(
            "橙色",
            200,
            new Date(),
            Arrays.asList("维生素A", "维生素C", "胡萝卜素")
        );
        carrotProducer.sendLuxuryCarrot(luxuryCarrot);
        
        // 测试延迟胡萝卜
        carrotProducer.sendDelayedCarrot("我是10秒后的胡萝卜", 10);
        
        log.info("所有胡萝卜已发送,请观察兔子们的表现!");
    }
    
    @Test
    void testMassProduction() {
        // 批量生产胡萝卜,测试性能
        for (int i = 1; i <= 100; i++) {
            carrotProducer.sendFreshCarrot("批量胡萝卜#" + i);
        }
        log.info("100根胡萝卜已投入生产线!");
    }
}

第九章:监控和运维

9.1 健康检查

management:
  endpoints:
    web:
      exposure:
        include: health,metrics,rabbit
  endpoint:
    health:
      show-details: always

9.2 自定义监控

@Component
public class RabbitMonitor {
    
    @Autowired
    private RabbitAdmin rabbitAdmin;
    
    public void checkRabbitHealth() {
        Properties queueProperties = rabbitAdmin.getQueueProperties("carrot.queue");
        if (queueProperties != null) {
            int messageCount = Integer.parseInt(
                queueProperties.get("QUEUE_MESSAGE_COUNT").toString()
            );
            log.info("胡萝卜队列当前有 {} 根胡萝卜等待处理", messageCount);
        }
    }
    
    /**
     * 定期清理积压消息
     */
    @Scheduled(fixedDelay = 60000) // 每分钟检查一次
    public void clearBacklog() {
        // 实现清理逻辑
        log.info("正在打扫兔子窝...");
    }
}

第十章:总结 —— 和兔子相处的秘诀

学到了什么:

  1. RabbitMQ 是个好邮差:可靠、灵活、功能强大的消息中间件
  2. SpringBoot 是兔子的好朋友:通过简单的配置就能轻松集成
  3. 消息确认很重要:别让胡萝卜在半路丢了
  4. 死信队列是保险箱:处理异常情况的最佳实践
  5. 延迟消息很实用:实现定时任务的好方法

实践建议:

  1. 给消息上保险:总是开启消息持久化和确认机制
  2. 合理设置TTL:别让胡萝卜放太久烂掉了
  3. 监控不能少:时刻关注兔子的健康状况
  4. 错误处理要优雅:准备好处理各种异常情况
  5. 性能要平衡:消费者数量不是越多越好

学习方向:

  1. 集群部署:养一群兔子,避免单点故障
  2. 镜像队列:给胡萝卜做备份
  3. 优先级队列:VIP 胡萝卜优先处理
  4. 流控机制:别把兔子撑坏了
  5. 与其他组件集成:让兔子和别的动物(其他中间件)合作

结尾:

记住,RabbitMQ 就像一只训练有素的邮差兔:

  • 发送消息,它接收
  • 发布消息,它路由
  • 消费消息,它确认
  • 搞砸了,它死信

只要遵循 RabbitMQ 的“兔子法则”,你的消息系统就会像兔子繁殖一样——快速、可靠、生生不息!

最后:虽然 RabbitMQ 很可爱,但请不要真的喂它胡萝卜,它只吃 0 和 1(二进制数据)!


代码仓库建议结构:

rabbitmq-demo/
├── src/main/java/com/example/rabbitmq/
│   ├── config/          # 配置类
│   ├── producer/        # 生产者
│   ├── consumer/        # 消费者
│   ├── dto/            # 数据传输对象
│   └── RabbitmqDemoApplication.java
├── src/main/resources/
│   └── application.yml
└── pom.xml

现在就去和你的 RabbitMQ 兔子做好朋友吧!记得每天喂它足够的消息,但别把它撑着了哦~

SpringBoot 整合 RabbitMQ:和这只“兔子”交朋友.png

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。


您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

相关文章
|
7天前
|
人工智能 Linux API
OpenClaw 阿里云秒级部署保姆级教程:从0到1搭建7×24小时AI助手
2026年3月,OpenClaw(原Clawdbot)凭借其轻量化架构、丰富技能生态与大模型适配能力,成为个人与小型团队搭建AI助手的首选方案。阿里云提供专属应用镜像与一键部署能力,可实现“秒级上线”,搭配百炼Coding Plan免费大模型API,无需本地算力即可拥有7×24小时在线的AI智能体。本文提供从服务器选购、端口放行、一键部署、模型配置到本地MacOS/Linux/Windows11联动的全流程保姆级教程,所有命令可直接复制执行,无冗余步骤,零基础也能一次成功。
233 11
|
2天前
|
人工智能 Linux API
OpenClaw(龙虾AI)入门详解:阿里云轻量服务器部署流程、模型配置与常见问题排查
OpenClaw(俗称Clawdbot,龙虾)并非传统意义上的对话式AI,而是一款基于MIT开源协议开发的本地优先AI智能体执行网关,核心价值在于将自然语言指令转化为实际操作,实现从“指令下达”到“任务落地”的全流程闭环。与单纯输出文字的AI不同,OpenClaw可直接操控设备系统、调用各类工具,完成文件管理、浏览器自动化、终端命令执行等实操任务,同时支持本地与云端多平台部署,兼顾数据隐私与运行稳定性。
182 5
|
22天前
|
人工智能 安全 API
OpenClaw(Clawdbot)阿里云/本地部署实战指南:百炼API配置流程 + 8个必装核心 Skill 详解
OpenClaw(原Clawdbot)作为2026年开源AI Agent领域的热门工具,其核心竞争力在于丰富的Skill生态系统。ClawHub作为官方技能商店,已收录13,000余个Skill,但其中多数需要编程基础或海外网络环境,普通用户难以直接使用。经过实测筛选,8个高频实用Skill脱颖而出——无需代码能力、零配置即可上手,覆盖技能发现、偏好记忆、内容总结、日常管理等核心场景,真正实现“装上就用”。
449 7
|
15天前
|
安全 Go API
Go 1.26 go fix 实战:一键现代化你的Go代码
2026年Go 1.26重磅升级`go fix`:从静态补丁工具跃升为智能重构引擎!支持全项目扫描、自动适配`errors.AsType`/`io.ReadAll`等新特性,提升性能与类型安全。本文带你三步上手、避坑实战,轻松实现代码现代化。(239字)
|
7天前
|
人工智能 数据可视化 Java
JBoltAI框架:Java企业转型AI开发的得力助手
JBoltAI是专为Java企业打造的AI开发框架,原生兼容Spring生态,支持事件驱动架构与可视化编排;内置RAG、知识图谱、Text2SQL等开箱即用能力;提供统一API、丰富文档及企业级服务,助力低门槛、高效率AI转型。(239字)
70 9
|
22天前
|
人工智能 安全 API
OpenClaw(Clawdbot)云端/本地部署+阿里云百炼API配置+安全 Skill 清单,恶意插件零接触指南
OpenClaw(原Clawdbot)的Skill生态已进入爆发期,ClawHub平台汇聚的5700+技能插件覆盖办公、开发、创作等全场景需求,让AI助手的能力边界无限延伸。但光鲜背后暗藏致命陷阱:Koi Security报告显示,约12%的Skill存在恶意行为,近期曝光的ClawHavoc供应链攻击中,黑客将恶意代码伪装成“加密钱包追踪器”,导致超1000名用户的API密钥被窃取、设备植入后门。
961 9
|
7天前
|
存储 安全 编译器
C语言「存储期四象限」:变量生死的底层宪法,90%内存bug的根源
本文深入剖析C语言四大存储期(静态、自动、分配、线程),揭示“变量消失”“指针错乱”“内存泄漏”等顽疾的根源——**访问了生命周期已结束的内存**。用四象限模型厘清变量生死规则,助你从底层杜绝90%内存bug。(239字)
108 15
|
7天前
|
Linux API 数据安全/隐私保护
OpenClaw跨平台协作指南|多端同步+阿里云/本地(Windows11/MacOS/Linux)部署+API配置实战指南
2026年,OpenClaw(Clawdbot)的跨平台协作能力已成为核心竞争力之一——用户不再局限于单一设备使用,通过多端同步机制,可在阿里云服务器、本地桌面设备(Windows11/MacOS/Linux)、移动终端之间实现配置同步、任务接续、数据共享,真正打破设备壁垒。这种“一处部署、多端可用”的协作模式,大幅提升了使用灵活性,适配移动办公、多场景切换等现代工作需求。
382 9
|
17天前
|
机器学习/深度学习 人工智能 自动驾驶
斑马线目标检测数据集(1000 张图片已划分、已标注)| AI训练适用于目标检测任务
本数据集含1000张真实道路图像(700训练/200验证/100测试),专注单类别“斑马线”目标检测,覆盖多场景、多视角、多光照及复杂干扰条件,标注规范(YOLO格式),兼容主流检测框架,适用于自动驾驶、ADAS、智慧交通等AI视觉任务。
|
2天前
|
人工智能 安全 Linux
保姆级图文教程:阿里云/本地部署OpenClaw 与必备 Skill 集合、免费大模型接入实战指南
2026 年的 OpenClaw 已经成为轻量化 AI 智能体的主流框架,但其原生能力仅能完成基础对话与文件操作,真正让它具备实用价值的核心是 Skill 扩展体系。ClawHub 上的技能数量已突破 25000 个,但盲目安装会导致冲突、上下文过载、安全风险上升等问题。本文整理一套真正高频、稳定、无冲突的必备 Skill 组合,同时提供 2026 年阿里云服务器、MacOS、Linux、Windows11 完整部署流程,以及阿里云百炼 Coding Plan 免费大模型 API 配置方法,所有步骤均为可直接执行的命令,零基础用户也能快速搭建稳定可用的智能体环境。
174 6