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("消息发送成功!");
}
相关推荐
Lxinccode2 小时前
Java查询数据库表信息导出Word-获取数据库实现[1]:KingbaseES
java·数据库·word·获取数据库信息·获取kingbasees信息
元亓亓亓2 小时前
Java后端开发day36--源码解析:HashMap
java·开发语言·数据结构
sd21315122 小时前
RabbitMQ 复习总结
java·rabbitmq
码银5 小时前
Java 集合:泛型、Set 集合及其实现类详解
java·开发语言
东阳马生架构5 小时前
Nacos简介—4.Nacos架构和原理
java
一只叫煤球的猫5 小时前
你真的会用 return 吗?—— 11个值得借鉴的 return 写法
java·后端·代码规范
颇有几分姿色6 小时前
Spring Boot 读取配置文件的几种方式
java·spring boot·后端
爱编程的鱼6 小时前
C# 枚举(Enum)声明与使用详解
java·windows·c#
人生导师yxc6 小时前
Spring MVC
java·spring·mvc
曹牧6 小时前
Java 调用webservice接口输出xml自动转义
java·开发语言·javascript