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("消息发送成功!");
}
相关推荐
yaoxin5211237 小时前
390. Java IO API - WatchDir 示例
java·前端·python
Halo_tjn8 小时前
Java 基于字符串相关知识点
java·开发语言·算法
梦想的颜色8 小时前
java 利用redis来限制用户频繁点击
java·开发语言
PH = 79 小时前
OverlayFS联合文件系统使用示例
java·linux·服务器
AC赳赳老秦10 小时前
OpenClaw进阶技巧:批量修改文件内容、替换关键词,解放双手
java·linux·人工智能·python·算法·测试用例·openclaw
Java小白笔记10 小时前
OpenClaw 实战方法论
java·开发语言·人工智能·ai·全文检索·ai编程·ai写作
呱牛do it10 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 5)
java·vue
练习时长一年10 小时前
Spring配置类的演化
java·spring boot·spring
喜欢流萤吖~11 小时前
服务间的依赖管理:微服务的协作之道
java·微服务
invicinble11 小时前
Spring如何把bean注册到容器里
java·后端·spring