java rabbitmq延时队列(开盖即食版)

原理

延时队列,消息放入队列中后,过了指定时间才被listener监听消费。

使用这种方式实现延时队列,我们首先要理清楚2个概念,TTL和死信队列。

一、TTL

TTL 全称 Time To Live(存活时间/过期时间)。当消息到达存活时间后,还没有被消费,会被自动清除。RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间。可以类比redis的TTL。

二、死信队列

死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机)。

那如何让一个普通的队列成为死信队列呢?

消息成为死信的三种情况:

(1) 队列消息长度到达限制;

(2)消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false;

(3) 原队列存在消息过期设置,消息到达超时时间未被消费;

此处让消息变成死信使用的是第三种情况。

给普通消息设置过期时间,过期后消息进入指定的死信队列被消费。

代码实现

1、添加springboot对amqp的支持

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2、mq配置类

@Configuration
public class CancelOrderMqConfig {

    // 普通队列
    public static final String CANCEL_ORDER_EXCHANGE = "hyb3.order.exchange";
    public static final String CANCEL_ORDER_QUEUE = "hyb3.order.queue";
    public static final String CANCEL_ORDER_ROUTINGKEY = "hyb3.order.routingkey";

    // 死信队列
    public static final String CANCEL_ORDER_DEAD_EXCHANGE = "hyb3.order.dead.exchange";
    public static final String CANCEL_ORDER_DEAD_QUEUE = "hyb3.order.dead.queue";
    public static final String CANCEL_ORDER_DEAD_ROUTINGKEY = "hyb3.order.dead.routingkey";

    // 声明普通交换机
    @Bean
    public DirectExchange normalExchange() {
        return new DirectExchange(CANCEL_ORDER_EXCHANGE);
    }

    // 声明死信交换机
    @Bean
    public DirectExchange deadExchange() {
        return new DirectExchange(CANCEL_ORDER_DEAD_EXCHANGE);
    }

    // 创建普通队列QUEUE
    @Bean
    public Queue normalQueue() {
        Map<String, Object> args = new HashMap<>(3);
        // 声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", CANCEL_ORDER_DEAD_EXCHANGE);
        // 声明当前队列的死信路由 key
        args.put("x-dead-letter-routing-key", CANCEL_ORDER_DEAD_ROUTINGKEY);
        // 声明队列的 TTL
        args.put("x-message-ttl", 5000); // 毫秒  5000毫秒 = 5s
        return QueueBuilder.durable(CANCEL_ORDER_QUEUE).withArguments(args).build();
    }

    // 把普通队列绑定到普通交换机上
    @Bean
    public Binding queueBindingNormalExchange() {
        return BindingBuilder.bind(normalQueue()).to(normalExchange()).with(CANCEL_ORDER_ROUTINGKEY);
    }

    // 声明死信队列
    @Bean
    public Queue deadQueue() {
        return new Queue(CANCEL_ORDER_DEAD_QUEUE);
    }

    // 把死信队列绑定到死信交换机上
    @Bean
    public Binding deadLetterBindingQAD() {
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with(CANCEL_ORDER_DEAD_ROUTINGKEY);
    }
}

3、发送消息到队列中

@RestController
@RequestMapping("/weChatPay")
public class WeChatPayController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostMapping("/testDelayMQ")
    public void testDelayMQ(String param) {
        rabbitTemplate.convertAndSend(CancelOrderMqConfig.CANCEL_ORDER_EXCHANGE, CancelOrderMqConfig.CANCEL_ORDER_ROUTINGKEY, param);
    }
}

4、listener监听消息并处理

@Component
public class DLXReceiver {

	@RabbitListener(queues = CancelOrderMqConfig.CANCEL_ORDER_DEAD_QUEUE)
	@RabbitHandler
	public void handler(Message message) {
		String string = new String(message.getBody());
		System.out.println("死信队列中接受到的消息:" + string);
		// 业务处理
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值