rabbitmq延时队列作用及代码编写

  1. 延时队列应用场景
    比如在下订单场景中,下订单之后有30分钟的时间去支付,如果30分钟之后订单还未支付则订单取消,如果每隔30分钟验证订单是否过期的方式(过期则判断是否支付成功,如果支付成功则订单生成,否则订单失效),那么在第一分钟下的订单请求可能要到第60分钟才能处理.延时过长.
    所以可以采用延时队列的方式,将下订单请求放到延时30分钟的队列中,30分钟之后将请求取出进行处理,如果下订单请求中已经支付成功,则下订单成功,否则失败.

  2. 延时队列使用图示
    在这里插入图片描述
    订单生成给交换机order-event-exchange,交换机中的消息放到order.delay.queue延时队列中,设定过30分钟超时后将消息放入order-event-exchange交换机中,然后交换机将超时的消息放入order.release.order.queue队列处理.

  3. 延时队列代码

  • pom.xml导入依赖包

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    
  • rabbitmq延时队列、交换机配置代码

    package com.kenai.gulimall.order.config;
    import com.kenai.gulimall.order.entity.OrderEntity;
    import com.rabbitmq.client.Channel;
    import org.springframework.amqp.core.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    @Configuration
    public class MyMQConfig {
        public void Listener(OrderEntity entity, Channel channel, Message message) throws IOException {
            System.out.println("收到过期的订单信息:准备关闭订单" + entity.getOrderSn());
            // 第一个参数: 发布的每一条消息都会获得一个唯一的deliveryTag,(任何channel上发布的第一条消息的deliveryTag为1,此后的每一条消息都会加1),
            // deliveryTag在channel范围内是唯一的
            // 第二个参数: 批量确认标志。如果值为true,则执行批量确认,此deliveryTag之前收到的消息全部进行确认; 如果值为false,则只对当前收到的消息进行确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
        /**
         * 死信队列
         * @return
         */
        @Bean
        public Queue orderDelayQueue(){
            Map<String, Object> arguments = new HashMap<>();
            // 死信队列消息过期后发送给orderEventExchange交换机
            arguments.put("x-dead-letter-exchange", "orderEventExchange");
            // 死信队列路由键为order.release.order,交换机根据该路由键将过期信息交给order.release.order.queue队列
            arguments.put("x-dead-letter-routing-key", "order.release.order");
            // 死信队列消息保持60s
            arguments.put("x-message-ttl", 60000);
            // durable: 持久化 即队列持久化保存到硬盘,如果服务重启 可以再次恢复队列
            // exclusive: 排他性 即队列只为当前链接绑定服务 链接binding断开 队列被删除
            // authDelete: 即消费者断开 队列被删除
            Queue queue = new Queue("order.delay.queue", true, false, false, arguments);
            return queue;
        }
    
        @Bean
        public Queue orderReleaseOrderQueue(){
            Queue queue = new Queue("order.release.order.queue", true, false, false);
            return queue;
        }
    
        @Bean
        public Exchange orderEventExchange(){
            return new TopicExchange("order-event-exchange", true, false);
        }
    
        /**
         * order-event-exchange交换机和order-delay-queue延时队列绑定,当有消息进来放入延时队列中
         * @return
         */
        @Bean
        public Binding orderCreateOrderBinding(){
            return new Binding("order.delay.queue",
                    Binding.DestinationType.QUEUE,
                    "order-event-exchange",
                    "order.create.order",
                    null);
        }
    
        /**
         * 延时队列中的消息过期后交给order-event-exchange交换机,然后根据路由键order.release.order,将消息交给order.release.order.queue队列
         * @return
         */
        @Bean
        public Binding orderReleaseOrderBinding(){
            return new Binding("order.release.order.queue",
                    Binding.DestinationType.QUEUE,
                    "order-event-exchange",
                    "order.release.order",
                    null);
        }
    }
    
  • 使用延时队列代码

package com.kenai.gulimall.order.controller;
import com.kenai.gulimall.order.entity.OrderEntity;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Date;
import java.util.UUID;

@Controller
public class HelloController {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @ResponseBody
    @GetMapping("/test/createOrder")
    public String createOrderTest(){
        OrderEntity entity = new OrderEntity();
        entity.setOrderSn(UUID.randomUUID().toString());
        entity.setModifyTime(new Date());
        // 交换机根据路由键order.create.order将消息entity发送给延时队列
        rabbitTemplate.convertAndSend("order-event-exchange", "order.create.order", entity);
        return "ok";
    }
}
  • 调用后等一分钟过期结果显示在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值