SpringBoot+RabbitMQ延时队列(插件版)

本文详细介绍了如何在SpringBoot项目中集成RabbitMQ的延迟队列功能,包括安装插件、配置文件、生产者和消费者实现,以及在实际场景如淘宝7天自动确认收货和12306订单处理中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot+RabbitMQ延时队列(插件版)

使用场景:淘宝7天自动确认收货,12306订单15分钟之内未支付等等…

1、安装地址

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

2、文件放到Linux文件下

rabbitmq安装目录plugins下

我的是 /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.18/plugins

3、执行命令

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

4、重启rabbitmq

rabbitmqctl stop

rabbitmq-server -detached

5、启动rabbitmq

浏览器访问有选中的交换机则安装成功

在这里插入图片描述

6、整合SpringBoot
1、依赖
    <dependencies>
        <!--SpringBoot-->
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.6.4</version>
        </dependency>
        <!--RabbitMQ-->
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.7.7</version>
        </dependency>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>
2、yaml
server:
  port: 5672

spring:
  application:
    name: hotel-rabbitmq
  rabbitmq:
    username: admin
    password: admin
    host: 192.168.132.128
    port: 5672
    virtual-host: /
    listener:
      simple:
        #手动确认机制
        acknowledge-mode: manual
    #开启true确认消息
    publisher-returns: true
    #消息发送到交换机上触发回调函数
    publisher-confirm-type: correlated
    template:
      mandatory: false #延时队列路由不生效解决方法
3、配置文件
package edu.hotel.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.BindException;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {
    /**交换机名称**/
    public static final String LAZY_EXCHANGE ="LazyExchange";
    /**队列名称**/
    public static final String LAZY_Queue ="LazyQueue";
    /**routingKey*/
    public static final String LAZY_KEY ="10000";


    @Bean
    public CustomExchange customExchange(){
        Map<String, Object> map = new HashMap<>();
        //设置交换机支持延迟消息推送
        map.put("x-delayed-type","direct");
        return new CustomExchange(LAZY_EXCHANGE,"x-delayed-message",true,false,map);
    }

    @Bean
    public Queue LazyQueue(){
        //测试设置不用持久化
        return new Queue(LAZY_Queue,false);
    }

    @Bean
    public Binding LazyBinding(){
        return BindingBuilder.bind(LazyQueue()).to(customExchange()).with(LAZY_KEY).noargs();
    }
}

4、生产者
package edu.hotel.rabbitmq.service.impl;

import edu.hotel.rabbitmq.service.RabbitMQService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@Slf4j
public class RabbitMQServiceImpl implements RabbitMQService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        /**
         * 消息发送到交换机成功回调函数
         */
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if (b){
                    log.info("消息投递到交换机成功");
                }else {
                    log.error("消息投递到交换机失败,原因->{}",s);
                }
            }
        });
        /**交换机投递到队列失败回调函数**/
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                log.error("投递到队列失败,错误原因->{}",returnedMessage.getMessage());
            }
        });
    }



    @Override
    public Boolean sendLazyMessage(String value) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        log.info("消息发送时间->{}",simpleDateFormat.format(new Date()));
        rabbitTemplate.convertAndSend("LazyExchange", routinKey, value, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                Integer key  = Integer.parseInt(RabbitMQConfig.LAZY_KEY);
                log.info("延迟时间->{}",key);
                //这个底层就是setHeader("x-delay",i);是一样的 设置延时时间
                message.getMessageProperties().setDelay(key);
                return message;
            }
        });
        return true;
    }
}

5、发送消息
   @GetMapping("/sendmessage")
    public String sendMessage(){
        rabbitMQService.sendLazyMessage("我是延迟消息");
        return "发送成功";
    }

在这里插入图片描述

6、消费者
/**
 * 消费者
 */
@Slf4j
@Component
public class RabbitMQConsumer {
    @RabbitListener(queues = "LazyQueue")
    public void lazyListener(String message, Channel channel, Message message2) throws IOException, InterruptedException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        log.info("消息接收时间->{}",simpleDateFormat.format(new Date()));
        log.info("消息内容是->{}",message);
        log.info("{}",message2.getMessageProperties().getDeliveryTag());
        Thread.sleep(10000);
        channel.basicAck(message2.getMessageProperties().getDeliveryTag(),false);
    }
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值