RabbitMQ延迟消息(通过死信交换机实现)

延迟消息:生产者发送消息时指定一个时间,消费者不会立刻收到消息,而是在指定时间后才收到消息

通过DLX和TTL模拟出延迟队列的功能,即,消息发送以后,不让消费者拿到,而是等待过期时间,变成死信后,发送给死信交换机再路由到死信队列进行消费

1、声明延迟队列

java 复制代码
package com.smart.wms.config.rabbitmq;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 功能描述:
 * 配置交换机、队列、绑定关系
 * @Authoer: bgq
 * @Date:2024/6/4 17:33
 */
@Configuration
public class MaterialStockExchangeConfig {

    public static final String MATERIAL_STOCK_EXCHANGE = "wms.material.exchange";
    public static final String MATERIAL_STOCK_QUEUE = "wms.material.queue";
    
    public static final String MATERIAL_DLX_DIRECT_EXCHANGE = "wms.dlx.exchange";
    public static final String MATERIAL_DLX_QUEUE = "wms.dlx.queue";

    public static final String MATERIAL_TTL__ROUTING_KEY = "ttl";
    public static final String MATERIAL_DLX_DELAYED_KEY = "dlx";


    @Bean
    public Queue ttlQueue() {
        return QueueBuilder.durable(MATERIAL_STOCK_QUEUE) // 指定队列的名称
            .ttl(10000) // 指定 TTL 为 10 秒,这里可设置过期时间也可以在发送消息时设置过期时间
            .deadLetterExchange(MATERIAL_DLX_DIRECT_EXCHANGE) // 指定死信交换机
            .deadLetterRoutingKey(MATERIAL_DLX_DELAYED_KEY) // 指定死信交换机的 RoutingKey
            .build();
    }

    /**
     * 声明TTl交换机
     */
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange(MATERIAL_STOCK_EXCHANGE);
    }

    /**
     * 声明ttl交换机与队列的关联关系
     */
    @Bean
    public Binding directBinding(){
        return BindingBuilder.bind(ttlQueue()).to(directExchange()).with(MATERIAL_TTL__ROUTING_KEY);
    }

    /**
     * 声明死信交换机
     */
    @Bean
    public DirectExchange dlxDirect(){
        return new DirectExchange(MATERIAL_DLX_DIRECT_EXCHANGE);
    }

    /**
     * 声明死信队列
     */
    @Bean
    public Queue dlxQueue(){
        return new Queue(MATERIAL_DLX_QUEUE);
    }

    /**
     * 声明死信交换机与队列关联关系
     */
    @Bean
    public Binding tlxBinding(){
        return BindingBuilder.bind(dlxQueue()).to(dlxDirect()).with(MATERIAL_DLX_DELAYED_KEY);
    }

}

2、监听死信队列消费

java 复制代码
@RabbitListener(queues = MaterialStockExchangeConfig.MATERIAL_DLX_QUEUE)//监听的队列
    public void process(Message message, Channel channel) throws Exception {
        // 进入消息消费业务逻辑
        String body = new String(message.getBody());
        log.info("消息,参数:{}",body);
        JSONObject bodyJson = JSONUtil.parseObj(body);
        //业务逻辑TODO
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}

3、发送消息

java 复制代码
@RequestMapping("/sendTTLMessage")
public void  sendTTLMessage(){
    JSONObject jsonObject = new JSONObject();
    jsonObject.putOpt("orderId",wmsSendOrder.getId());
    rabbitMQSendUtils.sendMessage(MaterialStockExchangeConfig.MATERIAL_STOCK_EXCHANGE,             
    MaterialStockExchangeConfig.MATERIAL_TTL__ROUTING_KEY, jsonObject, wmsSendOrder.getId().toString());
    log.info("消息发送成功!");
}
相关推荐
ningbaidexia36 分钟前
java数据结构集合复习之ArrayList与顺序表
java·数据结构·windows
程序员云翼2 小时前
7-理财平台
java·vue.js·spring boot·后端·毕设
舞者H2 小时前
源码层面学习动态代理
java·学习
焱行软件科技计算机毕设2 小时前
【java计算机毕设】线上花店销售商城系统java MySQL ssm JSP maven项目代码源码+文档ppt
java·mysql·课程设计
专注成就自我2 小时前
java使用easypoi模版导出word详细步骤
java·开发语言·word
多多*2 小时前
SpringBoot 启动流程六
java·开发语言·spring boot·后端·spring
极乐码农3 小时前
Spring学习03-[Spring容器核心技术IOC学习进阶]
java·学习·spring
m0_588383323 小时前
初学Spring之 JavaConfig 实现配置
java·spring
让你三行代码QAQ3 小时前
SpringSecurity初始化过程
java·开发语言
Enaium3 小时前
Rust入门实战 编写Minecraft启动器#1启动方法
java·后端·rust