Rabbit 实例

一、概述

在mq消息队列中主要分广播式消息、持久式消息、死信式消息。

**广播式(Fanout,如 hos_notice_task):**不看路由键、无脑复制,一条消息发给所有绑定的队列各一份------"公告群发,人人有份"(通知前端专用,发时路由键传空串)

**持久式/业务式(Topic/Direct,如 hos_topic → 各业务队列):**按"路由键=队列名"精确匹配投递,消息持久化躺在队列里等消费,一条消息只被处理一次------"一件活只干一遍,消息落地为安"

**死信(TTL + DLX 延时,如 hos_delay_exchange):**消息在源队列睡到 TTL 到期变死信,再按死信路由键转投实发队列、到点消费一次------"设个闹钟,到点才响"

一句话记忆:广播=群发复制,业务=点对点持久,死信=到点触发------三种模式对应三种诉求:"人人都要知道"、"一件活干一次"、"到时候再看结果"。

二、广播式

实例化示例如下:

java 复制代码
 public static final String NOTICE_FANOUT_NAME = "hos_notice_task";
 
 @Bean
 public FanoutExchange noticeFanoutExchange() {
     return new FanoutExchange(NOTICE_FANOUT_NAME, false, false);
 }

三、持久式/业务式

实例化示例如下:

java 复制代码
  public static final String TOPICS_NAME = "hos_topic";

  @Bean
  public TopicExchange hosTopicExchange() {
     return new TopicExchange(TOPICS_NAME, true, false);
  }

四、死信

实例化示例如下:

java 复制代码
public static final String DELAY_EXCHANGE = "hos_delay_exchange";

@Bean(DELAY_EXCHANGE)
public Exchange delayExchange() {
    return ExchangeBuilder.topicExchange(DELAY_EXCHANGE).durable(true).build();
}

五、队列(Queue)

实例化示例如下:

java 复制代码
public static final String TEST_SAVE_QUEUE_NAME = "hos_test_save";
    
@Bean
public Queue testSaveQueue() {
    return new Queue(TEST_SAVE_QUEUE_NAME, true);
}

队列(queue)的四种初始化函数

java 复制代码
new Queue(String name)
new Queue(String name, boolean durable)
new Queue(String name, boolean durable, boolean exclusive, boolean autoDelete)
new Queue(String name, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)

| 参数 | 含义 | 用法 |
|---|---|---|
| `name` | 队列名,全局唯一 | `hos_test`、`hos_test_save`... |
| `durable` | 队列定义**持久化**:broker 重启队列还在 | 全部 `true` |
| `exclusive` | 排他:只归声明它的连接用,连接断开即删 | 全部 `false`(业务队列要共享) |
| `autoDelete` | 最后一个消费者退出后自动删队列 | 全部 `false`(断连不删,消息要留存) |
| `arguments` | 扩展参数 Map:延时 / 死信 / 优先级都在这 | 优先级队列、死信源队列使用 |

注意:durable=true 只保**队列定义**,不保**消息**。消息要持久必须发布时标 deliveryMode=2;new Queue(name, true) 等价于 durable=true、exclusive=false、autoDelete=false。

六、绑定(Binding)

注意:绑定与队列成对出现,一个绑定对应一个队列

实例化示例如下:

java 复制代码
@Bean
public Binding bindingTestSaveQueue() {
   return BindingBuilder.bind(testSaveQueue()).to(hosTopicExchange()).with(TEST_SAVE_QUEUE_NAME);
}


new Binding(destination, destinationType, exchange, routingKey, arguments)

BindingBuilder.bind(队列).to(交换机).with(绑定键).noargs()

| 要素 | 含义 | 用法 |
|---|---|---|
| `destination` | 消息去哪 | `bind(队列)` |
| `destinationType` | 目标是队列还是交换机(支持交换机→交换机) | `QUEUE`(默认) |
| `exchange` | 消息从哪个交换机来 | `.to(hosTopicExchange())` / `.to(delayExchange())` |
| `key` | 绑定键:消息路由键与它相等/通配才投递 | 恒等于队列名(项目约定) |
| `arguments` | 绑定参数(headers 交换机的 `x-match` 等) | 无(`.noargs()`) |

七、arguments

实例化示例如下:

java 复制代码
Map<String, Object> arguments = new HashMap<>();
arguments.put("x-max-priority", 10);
arguments.put("x-dead-letter-exchange", DELAY_EXCHANGE);
arguments.put("x-dead-letter-routing-key", ACT_FIVE_MINUTE_NOTICE_QUEUE);
arguments.put("x-message-ttl", 60000 * 5);
return new Queue(TEST_QUEUE_NAME, true, false, false, arguments);

|---------------------------|------------------------------|
| 参数 | 含义 |
| x-message-ttl | 消息存活时间(**毫秒**),到期变死信/被丢弃 |
| x-dead-letter-exchange | 死信交换机:过期/被拒/超长后转投给谁 |
| x-dead-letter-routing-key | 死信路由键:转投时消息用什么键匹配 |
| x-max-priority | 优先级上限,值越大越先被消 |

八、发送端

发送消息统一用RabbitTemplate 的 convertAndSend 方法

实例化示例如下:

java 复制代码
//普通 JSON 消息(ProcessAutoSender)
rabbitTemplate.convertAndSend(
        RabbitConfig.TOPICS_NAME,                    // 交换机 hos_topic
        RabbitConfig.PREPROCESS_AUTO_QUEUE_NAME,     // 路由键 = 队列名
        jsonStr);                                    // 消息体:JSON 字符串

//带优先级(testSender,队列声明 x-max-priority=10)
rabbitTemplate.convertAndSend(
        RabbitConfig.TOPICS_NAME,
        RabbitConfig.TEST_QUEUE_NAME,
        jsonStr,
        msg -> {
            msg.getMessageProperties().setPriority(priority);
            return msg;
        });

//Fanout 广播(NoticeSender)------路由键必须传空串
rabbitTemplate.convertAndSend(RabbitConfig.NOTICE_FANOUT_NAME, "", JsonUtils.toJsonStr(notice));

九、接收端

接收:@RabbitListener + @RabbitHandler

@RabbitListener(queues=xxxx) 声明监听哪个队列

@RabbitHandler 标记处理方法

实例化示例如下:

java 复制代码
// 按 Map 解析
@RabbitListener(queues = RabbitConfig.TEST_SAVE_QUEUE_NAME)
@RabbitHandler
public void testSave(String message, Channel channel) {
    Map msg = JsonUtils.parseObject(message, Map.class);
    String test= (String) msg.get("test");
    ...
}

// 按 DTO 解析
@RabbitListener(queues = RabbitConfig.TEST_RESULT_QUEUE_NAME)
@RabbitHandler
public void cephResult(String message, Channel channel) {
    DTO resultDTO = JsonUtils.parseObject(message, DTO.class);
    Long taskId = resultDTO.getTaskId();
    ...
}

// Fanout 接收用匿名队列绑定(websocket NoticeConsumer):
@RabbitListener(bindings = @QueueBinding(
        value = @Queue,                                          // 匿名队列,自动生成
        exchange = @Exchange(value = RabbitConfig.NOTICE_FANOUT_NAME,
                             durable = "false", type = ExchangeTypes.FANOUT)))  // 没有 key
@RabbitHandler
public void noticeResult(String message, Channel channel) throws Exception {
    Map<String, String> notice = new HashMap<>();
    notice.put("type", "notice");
    notice.put("content", message);
    webSocketSessionManager.broadcast(JsonUtils.toJsonStr(notice)); 
}

十、结语

消息体统一 JSON 字符串,收发双方字段对齐,跨模块联调基本零歧义。如果你也在做微服务拆解、任务异步化,这套"交换机-队列-绑定-死信"的落地姿势可以直接抄作业。有任何细节欢迎评论区交流。

相关推荐
文丑颜不良啊18 分钟前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang1 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪2 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息2 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼3 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff4 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff4 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
David猪大卫4 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
SL_staff5 小时前
JVS数字底座实践:构建企业级统一内容管理平台的技术路径
java·产品
nice_lcj5206 小时前
【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端
java·后端·spring·spring ai·ai应用开发