美文网首页
springboot整合rabbitmq之-发送延时消息取消超时

springboot整合rabbitmq之-发送延时消息取消超时

作者: LRyab博客 | 来源:发表于2019-12-16 09:24 被阅读0次

1搭建项目开发环境

1.1安装rabbitmq

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端

1.2下载rabbitmq

安装rabbitmq,需要先安装 下载地址:http://erlang.org/download

安装如下图

安装RabbitMQ,下载地址:https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe

安装完成后,进入RabbitMQ安装目录下的sbin目录


image image.gif

     4.在地址栏输入cmd并回车启动命令行,然后输入以下命令启动管理功能:
     rabbitmq-plugins enable rabbitmq_management

5.访问地址查看是否安装成功:http://localhost:15672/

image image.gif

​​

1.3启动idea开始集成rabbitmq

  • 找到项目配置文件
#整合rabbitmq
rabbitmq:
  host: localhost
  ##服务器端口
  port: 5672
  virtual-host: /
  username: guest
  password: guest
  publisher-confirms: true #如果对异步消息需要回调必须设置为true
image.gif
  • 添加rabbitmq配置类
@Configuration
public class RabbitMqConfig {

    /**
     * 订单消息实际消费队列所绑定的交换机
     */
    @Bean
    DirectExchange orderDirect() {
        return (DirectExchange) ExchangeBuilder
                .directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
                .durable(true)
                .build();
    }

    /**
     * 订单延迟队列队列所绑定的交换机
     */
    @Bean
    DirectExchange orderTtlDirect() {
        return (DirectExchange) ExchangeBuilder
                .directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange())
                .durable(true)
                .build();
    }

    /**
     * 订单实际消费队列
     */
    @Bean
    public Queue orderQueue() {
        return new Queue(QueueEnum.QUEUE_ORDER_CANCEL.getName());
    }

    /**
     * 订单延迟队列(死信队列)
     */
    @Bean
    public Queue orderTtlQueue() {
        return QueueBuilder
                .durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
                .withArgument("x-dead-letter-exchange", QueueEnum.QUEUE_ORDER_CANCEL.getExchange())//到期后转发的交换机
                .withArgument("x-dead-letter-routing-key", QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())//到期后转发的路由键
                .build();
    }

    /**
     * 将订单队列绑定到交换机
     */
    @Bean
    Binding orderBinding(DirectExchange orderDirect, Queue orderQueue){
        return BindingBuilder
                .bind(orderQueue)
                .to(orderDirect)
                .with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey());
    }

    /**
     * 将订单延迟队列绑定到交换机
     */
    @Bean
    Binding orderTtlBinding(DirectExchange orderTtlDirect, Queue orderTtlQueue){
        return BindingBuilder
                .bind(orderTtlQueue)
                .to(orderTtlDirect)
                .with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
    }

}
image.gif
  • 配置生产者消费者类
@Component
public class CancelOrderSender {
    private static Logger LOGGER = LoggerFactory.getLogger(CancelOrderSender.class);
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendMessage(Long orderId,final long delayTimes){
        //给延迟队列发送消息
        amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //给消息设置延迟毫秒值
                message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
            }
        });
        LOGGER.info("send orderId:{}",orderId);
    }
}
image.gif
@Component
@RabbitListener(queues = "mall.order.cancel")
public class CancelOrderReceiver {
    private static Logger LOGGER = LoggerFactory.getLogger(CancelOrderReceiver.class);

    @RabbitHandler
    public void handle(Long orderId){
        LOGGER.info("消息被消费成功");
        LOGGER.info("process orderId:{}",orderId);
    }
}

image.gif
  • spring boot集成rabbitmq完成

2springboot集成rabbitmq应用场景


2.1用户下单超时未支付自动取消订单

订单取消功能:

一般情况下用户下单后,如果在120分钟以内还不支付,则此订单将会默认取消。

  1. 可以用定时任务每隔1分钟去扫描判断有没有超时的订单如果有,则直接取消订单。
  2. 第二种情况可以利用rabbitmq延时队列实现,用户下单那一时刻,则直接调用单个订单超时自动取消接口

2.2代码实现

2.2.1http请求服务层

@RestController
@RequestMapping("api")
public class OrderController {

    @Autowired
    private CancelOrderSender orderSender;
    @RequestMapping(value = "/cancelOrder",method = RequestMethod.POST)
    @ResponseBody
    public CommonResult cancelOrder(){
        //1分钟消息被消费 //单位毫秒
        orderSender.sendMessage(1L,60000);

        return CommonResult.success(null);
    }

}
image.gif

2.2.2业务逻辑服务层

@Component
public class CancelOrderSender {
    private static Logger LOGGER = LoggerFactory.getLogger(CancelOrderSender.class);
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendMessage(Long orderId,final long delayTimes){
        //给延迟队列发送消息
        amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //给消息设置延迟毫秒值
                message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
            }
        });
        LOGGER.info("send orderId:{}",orderId);
    }
}

image.gif

2.2.3代码测试

image image.gif

  • postman测试

  • 测试结果

    image
image.gif


用户下单成功消息延迟1分钟被消费

3总结

  1. 技术方向springboot如何整合rabbitmq实现消息队列
  2. 业务方向用户下单超时未支付订单如何处理,以及自己的实现思路

4个人说明

经验是由一点一点积累的,思维也是由一天一天训练出来的。

相关文章

网友评论

      本文标题:springboot整合rabbitmq之-发送延时消息取消超时

      本文链接:https://www.haomeiwen.com/subject/evsrnctx.html