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("消息发送成功!");
}
相关推荐
HerayChen5 分钟前
HbuilderX 内存溢出报错
java·大数据·linux
程序员小白条29 分钟前
0经验如何找实习?
java·开发语言·数据结构·数据库·链表
小马爱打代码40 分钟前
Spring AI:搭建自定义 MCP Server:获取 QQ 信息
java·人工智能·spring
郭涤生43 分钟前
QT 架构笔记
java·数据库·系统架构
daidaidaiyu1 小时前
基于LangGraph开发复杂智能体学习一则
java·ai
小小8程序员2 小时前
STL 库(C++ Standard Template Library)全面介绍
java·开发语言·c++
a努力。2 小时前
Redis Java 开发系列#2 数据结构
java·数据结构·redis
a努力。2 小时前
腾讯Java面试被问:String、StringBuffer、StringBuilder区别
java·开发语言·后端·面试·职场和发展·架构
Vic101014 小时前
解决 Spring Security 在异步线程中用户信息丢失的问题
java·前端·spring
QD_IT伟4 小时前
SpringBoot项目整合Tlog 数据链路的规范加强
java·spring boot·后端