Springboot集成RabbitMQ实现延时队列(实战电商平台超时取消)

前提条件:RabbitMQ安装

1.Windows下RabbitMq安装

windows环境下安装RabbitMQ(超详细),
2.linux下

Linux下安装RabbitMQ,点我跳转

无论是windwos还是linux安装的rabbit,开始编写代码前请确认rabbit运行状态。

http://IP:PORT:15672

以上是rabbitmq默认的可视化界面访问地址,账号密码默认为:guest/guest

如有需要修改默认账号密码:请点此链接跳转

一切准备就绪,开始发功

======================我是一条发功分界线=================================

1.给我们的maven项目添加依赖(springboot + maven)

打开我们项目的pom.xml,在dependencies标签中添加如下代码

        <!-- Rabbit MQ 依赖 begin -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Rabbit MQ 依赖 end -->

添加了以后记得maven重新加载一下哈,不然后面添加的代码有可能会报依赖错误。

2.添加rabbitmq的配置.springboot可以放在bootstrap.yml

spring: 
  rabbitmq:
    host: slave.taskwall.net   #rabbit安装地址
    port: 5672                 #端口,默认为5672
    username: guest     
    password: guest
    virtual-host: /            #请注意这里,如果没有配对有可能会在启动时报错,报连不上rabbit
virtual-host:

具体配置应为username对应的host,具体可以登录rabbitmq,查看。

登录rabbit界面管理,IP:PORT:15672,对应的账号登录后找到admintab页面

填写账户对应virtual--host,如图所示:

 -----------------------------------------至此,配置完成,开发代码部分-----------------------------------------

1.----------------新建RabbitMQConfiguration.java

*********************用户队列的配置:队列名称,交换机名称,死信队列************

你可以先照搬这个代码,当做demo

package com.taskwall.member.util;


import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.HashMap;
import java.util.Map;

/**
 * @author Gemini Wong
 * @date 2022-03-23 22:46
 */

@Configuration
public class RabbitMQConfiguration {
    //队列名称
    public   final static String orderQueue = "order_queue";

    //交换机名称
    public  final static String orderExchange = "order_exchange";

    // routingKey
    public  final static String routingKeyOrder = "routing_key_order";

    //死信消息队列名称
    public  final static String dealQueueOrder = "deal_queue_order";

    //死信交换机名称
    public  final static String dealExchangeOrder = "deal_exchange_order";

    //死信 routingKey
    public final static String deadRoutingKeyOrder = "dead_routing_key_order";

    //死信队列 交换机标识符
    public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";

    //死信队列交换机绑定键标识符
    public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Bean
    public Queue orderQueue() {
        // 将普通队列绑定到死信队列交换机上
        Map<String, Object> args = new HashMap<>(2);
        //args.put("x-message-ttl", 5 * 1000);//直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活
        //这里采用发送消息动态设置延迟时间,这样我们可以灵活控制
        args.put(DEAD_LETTER_QUEUE_KEY, dealExchangeOrder);
        args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKeyOrder);
        return new Queue(RabbitMQConfiguration.orderQueue, true, false, false, args);
    }

    //声明一个direct类型的交换机
    @Bean
    DirectExchange orderExchange() {
        return new DirectExchange(RabbitMQConfiguration.orderExchange);
    }

    //绑定Queue队列到交换机,并且指定routingKey
    @Bean
    Binding bindingDirectExchangeDemo5(   ) {
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(routingKeyOrder);
    }

    //创建配置死信队列
    @Bean
    public Queue deadQueueOrder() {
        Queue queue = new Queue(dealQueueOrder, true);
        return queue;
    }

    //创建死信交换机
    @Bean
    public DirectExchange deadExchangeOrder() {
        return new DirectExchange(dealExchangeOrder);
    }

    //死信队列与死信交换机绑定
    @Bean
    public Binding bindingDeadExchange() {
        return BindingBuilder.bind(deadQueueOrder()).to(deadExchangeOrder()).with(deadRoutingKeyOrder);
    }
}

2.----------------业务部分将订单加入队列

//Rabbit延时队列,处理订单自动取消
        this.rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.orderExchange,
                RabbitMQConfiguration.routingKeyOrder,
                twOrder.getOrderId()
                , message -> {
                    message.getMessageProperties().setExpiration(1000 * 10 + "");
                    return message;
                });

rabbitTemplate需要引入一下jar包:

    @Resource
    private AmqpTemplate rabbitTemplate;

好了。到此已经做掉了新增订单时,将订单放入mq的队列中,其中setExpiration是设置过期时间。你可以设置成30分钟或者15分钟,看业务需要,我们做demo的时候可以设置成5s/10s(单位是毫秒,所以要乘以1000)

2.----------------订单到时间后,触发自动取消

附上代码:OrderFailureListener

值得注意的是这边的注解@RabbitListener( queues = RabbitMQConfiguration.dealQueueOrder )

也就是对应的是RabbitMQConfiguration配置中的一个队列

也就是说你有多个业务需要延时操作的,你就可以创建多个队列来实现

package com.taskwall.member.util;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * @author Gemini Wong
 * @date 2022-03-23 22:51
 */

@Component
public class OrderFailureListener {
    @RabbitListener(
            queues = RabbitMQConfiguration.dealQueueOrder
    )
    public void process(String order, Message message, @Headers Map<String, Object> headers, Channel channel) throws IOException {

        // 判断订单是否已经支付,如果支付则;否则,取消订单(逻辑代码省略)
        System.out.println("订单编号:" + order + ";因超时自动取消");
    }
}

订单取消的业务逻辑这边就不加上去了。

无非就是先判断订单是否成功支付,没有支付就取消订单。

*******************************2022-04-12更新已完成***********************************

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Spring Boot 中,你可以通过 RabbitMQ 的 `x-delayed-message` 插件来实现延时队列,而不需要使用额外的插件或库。下面是实现步骤: 1. 添加依赖 在 `pom.xml` 文件中添加 RabbitMQ 的依赖: ```xml <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>2.3.12.RELEASE</version> </dependency> ``` 2. 配置 RabbitMQ 的 `x-delayed-message` 插件 在 RabbitMQ 中,你需要先安装 `x-delayed-message` 插件。你可以通过 `rabbitmq-plugins` 命令来安装插件: ``` rabbitmq-plugins enable rabbitmq_delayed_message_exchange ``` 或者,你可以在 `rabbitmq.conf` 文件中添加以下配置,然后重启 RabbitMQ: ``` plugins.rabbitmq_delayed_message_exchange = {git, "https://github.com/rabbitmq/rabbitmq-delayed-message-exchange", {branch, "master"}} ``` 3. 配置 RabbitMQ 的连接信息 在 `application.properties` 中添加 RabbitMQ 的连接信息: ```properties spring.rabbitmq.host=your-rabbitmq-host spring.rabbitmq.port=5672 spring.rabbitmq.username=your-rabbitmq-username spring.rabbitmq.password=your-rabbitmq-password ``` 4. 定义队列和交换器 在 Spring Boot 中,你可以使用 `@Configuration` 和 `@Bean` 注解来定义队列和交换器。下面是一个例子: ```java @Configuration public class RabbitConfig { @Bean public Queue delayedQueue() { return QueueBuilder.durable("delayed.queue") .withArgument("x-dead-letter-exchange", "normal.exchange") .withArgument("x-dead-letter-routing-key", "normal.routingkey") .build(); } @Bean public CustomExchange delayedExchange() { Map<String, Object> args = new HashMap<>(); args.put("x-delayed-type", "direct"); return new CustomExchange("delayed.exchange", "x-delayed-message", true, false, args); } @Bean public Binding binding() { return BindingBuilder.bind(delayedQueue()) .to(delayedExchange()) .with("delayed.routingkey") .noargs(); } } ``` 在上面的例子中,我们定义了一个 `delayedQueue` 队列,它的死信交换器是 `normal.exchange`,死信路由键是 `normal.routingkey`。我们还定义了一个 `delayedExchange` 交换器,它的类型是 `x-delayed-message`,并将 `x-delayed-type` 属性设置为 `direct`。最后,我们将 `delayedQueue` 队列绑定到 `delayedExchange` 交换器上,并使用路由键 `delayed.routingkey`。 5. 发送延时消息 你可以使用 `RabbitTemplate` 类来发送消息到 `delayedQueue` 队列。在发送消息时,你需要将消息的 `headers` 属性设置为 `x-delay`,并将值设置为消息的延时时间(单位为毫秒)。 ```java @Autowired private RabbitTemplate ### 回答2: 在Spring Boot中实现RabbitMQ延时队列需要以下几个步骤: 1. 首先,我们需要定义一个交换机(Exchange),用于将消息发送到延时队列中。可以使用DirectExchange、TopicExchange或FanoutExchange等不同类型的交换机。交换机的类型根据具体的业务需求而定。 2. 接下来,我们需要定义两个队列,一个为延时队列,另一个为业务队列延时队列用于接收需要延时处理的消息,业务队列用于接收延时队列中处理完成的消息。 3. 创建并配置消息发送和接收的相关组件。使用RabbitTemplate来发送消息到延时队列,创建一个消费者来接收延时队列中的消息并处理。 4. 在消息发送时,可以通过给消息设置不同的过期时间来实现延时功能。在发送消息时,将消息携带的延时时间设置为过期时间,然后发送到延时队列中。 5. 在消费者中,监听业务队列,当接收到延时队列中的消息时,进行相应的处理,例如发送邮件、生成报表等。 这样就实现RabbitMQ延时队列的功能。通过设置消息的过期时间,可以控制消息何时被消费。延时队列可以在某个特定的时间点将消息转发到业务队列,完成后续处理。Spring Boot提供了简单而强大的集成,可以轻松实现延时队列的功能。 ### 回答3: 实现RabbitMQ延时队列的核心思想是利用RabbitMQ的插件(x-delayed-message)和Spring Boot的消息中间件(RabbitTemplate)结合使用。 首先,确保在RabbitMQ服务中安装了插件。在RabbitMQ的安装目录下,执行以下命令: ``` rabbitmq-plugins enable rabbitmq_delayed_message_exchange ``` 接下来,在Spring Boot项目的pom.xml文件中添加RabbitMQ的依赖: ```xml <dependencies> <!-- RabbitMQ --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> </dependencies> ``` 然后,创建一个配置类,用于连接RabbitMQ服务和创建延时队列: ```java @Configuration public class RabbitMQConfig { @Autowired private Environment env; @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setAddresses(env.getProperty("spring.rabbitmq.addresses")); connectionFactory.setUsername(env.getProperty("spring.rabbitmq.username")); connectionFactory.setPassword(env.getProperty("spring.rabbitmq.password")); return connectionFactory; } @Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory()); rabbitTemplate.setMessageConverter(jsonMessageConverter()); return rabbitTemplate; } @Bean public MessageConverter jsonMessageConverter() { return new Jackson2JsonMessageConverter(); } @Bean public Exchange delayedExchange() { Map<String, Object> args = new HashMap<>(); args.put("x-delayed-type", "direct"); return new CustomExchange("delayed-exchange", "x-delayed-message", true, false, args); } @Bean public Queue delayedQueue() { return new Queue("delayed-queue", true); } @Bean public Binding delayedBinding() { return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with("delayed-routing-key").noargs(); } } ``` 在上述代码中,我们创建了一个自定义的Exchange,将其类型设置为"x-delayed-message",并创建了一个延时队列,将其绑定在这个Exchange上。这样,消息发送到这个Exchange时,会根据消息中的延时时间属性进行延时处理。 最后,我们可以通过RabbitTemplate发送延时消息: ```java @Service public class RabbitMQService { @Autowired private RabbitTemplate rabbitTemplate; public void sendDelayedMessage(String message, int delayTime) { rabbitTemplate.convertAndSend("delayed-exchange", "delayed-routing-key", message, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setHeader("x-delay", delayTime); return message; } }); } } ``` 在上述代码中,我们通过rabbitTemplate将消息发送到名为"delayed-exchange"的Exchange上,并设置消息的延时时间属性"x-delay"。最后,通过"convertAndSend"方法发送消息。 以上就是使用Spring Boot实现RabbitMQ延时队列的简单示例。通过这种方式,我们可以轻松地实现消息的延时处理,使得系统更加灵活和高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值