rabbitmq延迟队列结合demo实际使用

本文介绍了如何利用RabbitMQ的延迟队列特性来实现在电商平台中,当用户下单但未支付时,订单经过一定时间后自动取消的功能。通过配置交换机、队列和路由键,发送带有延迟的消息到队列中,然后由消费者监听该队列,在指定时间后处理订单取消操作。这种方式确保了业务流程的自动化和准确性。
摘要由CSDN通过智能技术生成

常见的使用场景:外卖或电商类平台中用户下单却不打算支付的时候,订单会进入到计时,直至一段时间后自动取消订单。还有等等的其他场景

本次应用与上述场景

引入依赖,配置号yml中的配置后

准备

配置队列和交换机


@Slf4j
@Configuration
public class RabbitMQConfig {

    //交换机
    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    //队列
    public static final String DELAYED_QUEUE_NAME = "delayed.queue";
    //routingKey
    public static final String DELAYED_ROUTING_KEY = "delayed.routingKey";
    //队列
    @Bean
    public Queue delayedQueue(){
        return new Queue(DELAYED_QUEUE_NAME);
    }
    //交换机
    @Bean
    public CustomExchange delayedExchange(){
        Map<String,Object> arguments = new HashMap<>();
        arguments.put("x-delayed-type","direct");
        /*
        1.交换机名称
        2.交换机类型
        3.是否持久化
        4.是否自动删除
        5.其他参数
         */
        return new CustomExchange(DELAYED_EXCHANGE_NAME,"x-delayed-message",
                true,false,arguments);
    }
    //绑定
    @Bean
    public Binding delayedQueueBindingExchange(@Qualifier("delayedQueue") Queue delayedQueue,
                                               @Qualifier("delayedExchange") CustomExchange delayedExchange){


        return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(DELAYED_ROUTING_KEY).noargs();
//自定义的交换机需要加.noargs()
    }

}

写下发送消息的类


@Service
@Slf4j
public class MQSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    public void sendMsg(String message, Integer delayTime){
        log.info("当前时间:{},发送时长{}毫秒的信息给延迟队列delayed.queue:{}",
                new Date().toString(),delayTime,message);

        rabbitTemplate.convertAndSend(RabbitMQConfig.DELAYED_EXCHANGE_NAME,
                RabbitMQConfig.DELAYED_ROUTING_KEY,message, message1 -> {
                    //发送延迟消息 延迟时长  ms
                    message1.getMessageProperties().setDelay(delayTime);
                    return message1;
                });
    }



}

消费者中涉及功能先不写,暂时先这样

@Slf4j
@Component
public class DelayQueueConsumer {
    //开始监控
    @RabbitListener(queues = DelayedQueueConfig.DELAYED_QUEUE_NAME)
    public void receiveDelayQueue(Message message){
        String msg = new String(message.getBody());
        log.info("当前时间:{},收到延迟队列消息:{}",new Date().toString(),msg);
    }
}

结合需要的功能

用户未支付的请求发发过来,我们同时去将订单的编号作为消息发送

/**
     * 用户下单但是没有支付
     *
     * @param orders
     * @return
     */
    @PostMapping("/submit1")
    public Result<String> submit1(@RequestBody Orders orders){
        log.info("取消支付订单--{}",orders);

        Long submitId = ordersService.submit(orders, 1);
        String id = ""+submitId;
        mqSender.sendMsg(id,10000);//把订单号的信息发送
        return Result.success("取消成功");
    }

往消费者中增添功能,固定时间后消费者就会接收到队列,从而去处理


@Component
@Slf4j
public class MQReceiver {
    @Autowired
    private OrdersService ordersService;
    @RabbitListener(queues = RabbitMQConfig.DELAYED_QUEUE_NAME)
    public void receive(Message message){
        //接受到订单号的信息的话就对比订单的支付情况 删掉
        String msg = new String(message.getBody());
        log.info("当前时间:{},收到延迟队列消息:{}",new Date().toString(),msg);
        BigInteger id = new  BigInteger(msg);
        Orders byId = ordersService.getById(id);
        Integer status = byId.getStatus();
        if(status==1){
            byId.setStatus(5);
            ordersService.updateById(byId);
            log.info("超时已经取消订单:{}",id);
        }
    }

}

就成功的完成了。

总结

很多东西都是看起来简单做起来难,刚学完一个技术的时候,有时候不知道怎么去应用,感觉毫无头绪,无从下手,也不知道实际的情况下到底是怎么应用的。但是当我们克服这些困难之后,从一些小的地方去实际使用了之后,就发现,其实一切可能都没有那么难,那些扑朔迷离的流程其实从一开始就很简单,只不过当我们缺乏指点和经验的时候什么都是困难的,当我们有了一点实际经验之后更多的收获是面对这个技术的底气吧

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值