rabbitMq延迟队列的使用

简介

这次打算说一下rabbitmq的延迟队列。

延迟队列,名字中有个队列,队列是先进先出的。所以说延迟队列是一个有方向性的。

其次,延迟队列和普通队列最大的区别就是,普通队列里的消息是希望自己早点被取出来消费。而延迟队列中的消息都是由时间来控制的。也就是说,他们进入队列的时候,就已经被安排何时被取出了

rabbitmq实现延迟队列主要有种方式。

第一种是使用普通队列和死信队列来模拟实现延迟的效果。大致上是将消息放入一个没有被监听的队列上,设置TTL(一条消息的最大存活时间)为延迟的时间,时间到了没有被消费,直接成为私信。监听私信队列来进行操作。

第二种是使用rabbitmq官方提供的delayed插件来真正实现延迟队列。本文对第二种进行详解

应用场景

  • 订单超时支付取消订单
  • 用户发起退款卖家3天不处理自动退款
  • 预约抢购活动,活动开始前10分钟短信通知用户

安装延迟插件

默认交换机是有4种模式的

rabbitMq延迟队列的使用_第1张图片

 现在我们去安装延迟插件

https://www.rabbitmq.com/community-plugins.html 前往官网去下载延迟插件

rabbitMq延迟队列的使用_第2张图片

 rabbitMq延迟队列的使用_第3张图片

 下载完成之后,上传到我们的服务器。使用下面的命令将插件复制到mq容器的plugins目录下

docker cp rabbitmq_delayed_message_exchange-3.10.2.ez rabbitmq:/plugins

rabbitMq延迟队列的使用_第4张图片

交换机新增一个延迟模式

rabbitMq延迟队列的使用_第5张图片

配置类

上代码,首先是我们的配置类。初始化一个队列和一个延迟交换机(这里我交换机模式用的是路由模式)。将队列绑定到交换机上并设置路由Key

@Component
public class RabbitmqDelayedConfig {

    /**
     * 初始化延迟交换机
     * @return
     */
    @Bean
    public CustomExchange delayedExchangeInit() {
        Map args = new HashMap<>();
        // 设置类型,可以为fanout、direct、topic
        args.put("x-delayed-type", "direct");
        // 第一个参数是延迟交换机名字,第二个是交换机类型,第三个设置持久化,第四个设置自动删除,第五个放参数
        return new CustomExchange("delayed_exchange","x-delayed-message", true,false,args);
    }

    /**
     * 初始化短信队列
     * @return
     */
    @Bean
    public Queue delayedSmsQueueInit() {
        return new Queue("sms_delayed_queue", true);
    }


    /**
     * 短信队列绑定到交换机
     * @param delayedSmsQueueInit
     * @param customExchange
     * @return
     */
    @Bean
    public Binding delayedBindingSmsQueue(Queue delayedSmsQueueInit, CustomExchange customExchange) {
        // 延迟队列绑定延迟交换机并设置RoutingKey为sms
        return BindingBuilder.bind(delayedSmsQueueInit).to(customExchange).with("sms").noargs();
    }
}

 生产者

将消息转发到"delayed_exchange"交换机上路由键为"sms"的队列中

@Component
@Log4j2
public class Producer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 延迟模式
     * @param msg 消息
     * @param time 延迟时间
     */
    public void delayedTest(String msg,Integer time) {
        // 第一个参数是延迟交换机名称,第二个是Routingkey,第三个是消息主题,第四个是X,并设置延迟时间,单位		是毫秒
        rabbitTemplate.convertAndSend("delayed_exchange","sms",msg,a -> {
            a.getMessageProperties().setDelay(time);
            return a;
        });
        log.info("延迟模式默认交换机已发出消息");
    }

}

消费者 

监听指定的队列。一旦队列中有消息则立刻取出进行消费

@Component
@Log4j2
public class ConsumerDelayed {

    /**
     * 延迟模式短信消费者
     * @param message
     */
    @RabbitListener(queues = {"sms_delayed_queue"})
    public void getSmsConsumer(String message) {
        log.info(new Date().toLocaleString() + "延迟模式短信消费者接收到信息:" + message);
    }

}

 发出消息并且10S后延迟队列对消息进行消费

更多知识请移步个人博客:33sora.com

你可能感兴趣的:(rabbitmq,分布式,java)