MQ根据正常队列、死信队列来实现延迟队列的场景

 1、在RabbitMQ的管理后台新建交换机(exchange);

  名称(Name): **ParkingExchange**

  类型(Type): **fanout**

  持久化(Durability): **Durable**

2、在RabbitMQ的管理后台新建队列(queue);

  名称(Name): **ParkingQueue**

  类型(Type): **Classic**(新版本RabbitMQ需要选)

  持久化(Durability): **Durable**

  参数设置(Arguments): 

    x-message-ttl = 3000(点下边的Message TTL)

    x-dead-letter-exchange = Ump_mq(点下边的Dead letter exchange, 然后填写Ump_mq)

3、在RabbitMQ的管理后台设置交换机**ParkingExchange**的Binding中的**To Queue**为**ParkingQueue**;

4、以上设置了队列ParkingQueue, 其消息的生命周期为3000毫秒, 即进入此队列的消息3秒会死掉, 死掉的消息会进去dead-letter-exchange为Ump_mq的交换机, 也就是实现了3秒延迟的后半部分.  

 

总结:

  正常队列A、死信队列B进行绑定;

  当数据放入死信队列B,并设置过期时间,数据过期之后,数据会从死信队列B重新放入正常队列A,此时监听器(正常队列A)会监听到消息并消费当前数据;

 

代码示例:

    public void pushOrderWxPayDelayData(Long orderId,Long orgId){
        //正常队列的key
        String routingKey = "klota3.0.order.wx.ispay.key.*.*";

        //死信队列的名称
        String delayQueueName = "mq-clota-order-wx-ispay-delay-queue";
        //死信队列的Key
        String delayQueueKey  = "klota3.0.order.wx.ispay.delay.key.*.*";
        try {
            //1、将当前正常队列与死信队列绑定
            rabbitMqManager.declareAndBindQueue(new TopicExchange("mq-clota-notice-topic-exchange"),
                    10, "mq-clota-notice-topic-exchange",routingKey,
                    Collections.singletonMap(delayQueueName, delayQueueKey));
        } catch (Exception e) {
            e.printStackTrace();
        }

        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("orderId", orderId);
        headerMap.put("orgId", orgId);
        MqSyncVo mqSyncVo = new MqSyncVo();
        mqSyncVo.setMessageId(String.valueOf(orderId));
        mqSyncVo.setSyncType(String.valueOf(orgId));
        /** 推送消息 **/
        Long seconds = 30L;
        String obj = redisUtil.getValue(String.format(RedisKeys.ORDER_WX_ISPAY_COUNT_KEY, orderId, orgId));
        //当前死信队列的key,当前key与上方 delayQueueKey klota3.0.order.wx.ispay.delay.key.*.* 能匹配上
        String delayRoutingKey  = "klota3.0.order.wx.ispay.delay.key.016.909";
        //2、将数据推送到死信队列,30S后过期,30S后过期的数据会从死信队列返回到正常队列,则正常队列中监听到数据会进行消费,则根据正常队列、死信队列来实现了延迟队列的场景
        rabbitMqManager.sendJsonMsgForTranAfterCommit(RabbitMqConst.NOTICE_TOPIC_EXCHANGE, delayRoutingKey, mqSyncVo, headerMap, Duration.ofSeconds(30L), Boolean.FALSE, null);
    }
posted @ 2024-08-28 11:55  DHaiLin  阅读(8)  评论(0编辑  收藏  举报