RabbitMQ延时队列插件实现

死信队列+延时队列存在的问题

由于传统的延时队列+死信队列实现自动取消订单的延时任务一下子就需要在RabbitMQConfig文件中配置6个方法,这样会比较麻烦,而且消息消费顺序是采用先进先出的规则,不能够实现第1条消息过期时间为10分钟,第2条消息的过期时间少于第1条的存活时间,导致第二条消息不能及时消费,这个时候引入RabbitMQ的延时队列插件即可解决这两个问题。

介绍

RabbitMQ的延时队列插件采用的是过期时间到了就消费的规则,不像其他队列是根据先进先出的规则进行消费,使用延时队列插件可以完成各种各样的延时任务,比如:不同时长的会员自动过期、自动取消订单等延时任务。下面我们以自动取消订单为例,做一个demo。

一、安装

1、在windows下进行安装

1)、下载和安装

csdn下载地址:https://download.csdn.net/download/ppjsyw/85055786(无需积分即可下载)

下载完成之后将文件复制到RabbitMQ的plugins目录

2)、启用插件

先切换到RabbitMQ的sbin目录,然后输入如下命令启用插件

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

之后重启RabbitMQ服务即可

二、引入依赖

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

三、修改application.yml

server:
  port: 80

spring:
  rabbitmq:
    host: localhost # 地址
    port: 5672 # 端口号
    virtual-host: / #虚拟host
    username: guest # 用户名
    password: guest # 密码
    publisher-confirms: true #如果对异步消息需要回调必须设置为true

四、在RabbitMqConfig配置队列、交换机和路由key

package com.hq.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

/**
 * @Author master
 * @Date: 2022/3/30 15 13 52
 */
@Configuration
public class RabbitMqConfig {
    /**
     * 取消订单队列
     */
    @Bean
    public Queue cancelOrderQueue() {
        return new Queue("cancelOrder");
    }

    /**
     * 取消订单交换机
     *
     * @return
     */
    @Bean
    CustomExchange cancelOrderExchange() {
        HashMap<String, Object> args = new HashMap<>(8);
        args.put("x-delayed-type", "direct");
        return new CustomExchange("cancelOrder_exchange", "x-delayed-message", true, false, args);
    }

    /**
     * 队列绑定交换机
     * @param cancelOrderExchange
     * @param cancelOrderQueue
     * @return
     */
    @Bean
    Binding cancelOrderBinding(CustomExchange cancelOrderExchange, Queue cancelOrderQueue) {
        return BindingBuilder.bind(cancelOrderQueue)
                .to(cancelOrderExchange)
                .with("cancelOrder")
                .noargs();
    }
}

五、发送消息

rabbitTemplate.convertAndSend("cancelOrder_exchange", "cancelOrder", "aaa",
        msg -> {
            msg.getMessageProperties().setDelay(30 * 1000);
            return msg;
        });

注:存活时间单位是毫秒,存活时间最多也就是int的最大值

发送成功之后,我们可以看到在交换机的messages delayed已经有了一条消息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aK7uHQRP-1648625654262)(C:\Users\master\AppData\Roaming\Typora\typora-user-images\image-20220330152551887.png)]

六、接收消息

package com.hq.rabbitmq.component;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.IOException;

/**
 * @Author master
 * @Date: 2022/3/30 15 26 46
 */
@Component
@RabbitListener(queues ="cancelOrder")
public class CancelOrderConsumer {
    @RabbitHandler
    public void handle(String content, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        try {
            System.out.println(content);
            //确认消费
            channel.basicAck(tag,false);
        } catch (Exception e){
            //消息重发
            channel.basicNack(tag,false,false);
            throw  new RuntimeException(e);
        }
    }
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值