RabbitMQ实现消息队列延迟功能

要实现 RabbitMQ 的消息队列延迟功能,一般采用官方提供的插件 “rabbitmq_delayed_message_exchange” 来实现。但 RabbitMQ 版本必须是 3.5.8 以上才支持该插件,否则得用其“死信”功能。

1、安装RabbitMQ延迟插件

(1)检查插件

使用 rabbitmq-plugins list 命令用于查看RabbitMQ安装的插件。

打开一个新的cmd窗口(按快捷键“Win+R”,输入“cmd”)。

运行命令:rabbitmq-plugins list

检查RabbitMQ插件安装情况:

(2)下载插件

如果没有安装插件,则直接访问官网进行下。

官方下载地址:https://www.rabbitmq.com/community-plugins.html

扫描二维码关注公众号,回复: 12710961 查看本文章

(3)安装插件

下载完成后,将其解压到 RabbitMQ 的 plugins 目录,如本人的目录路径为:D:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.9\plugins

打开一个新的cmd窗口(按快捷键“Win+R”,输入“cmd”)。

如果系统已经配置 RabbitMQ 环境变量,则执行下面的命令进行安装。

运行命令:rabbitmq-plugins enable rabbitmq_delayed_message_exchange

2、实现RabbitMQ消息队列延迟功能

【示例】创建 SpringBoot 项目,实现 RabbitMQ 消息队列延迟功能。

(1)使用Maven添加依赖文件

在pom.xml配置信息文件中,添加相关依赖文件:

<!-- AMQP客户端 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>2.4.1</version>
</dependency>

(2)RabbitMQ的配置

在 application.yml 配置文件中配置 RabbitMQ 信息:

spring:
  # 项目名称
  application:
    name: rabbitmq-delayed
  # RabbitMQ服务配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

(3)RabbitMQ配置类

创建 com.pjb.config 包,并创建 RabbitMqConfig 类(RabbitMQ配置类),配置交换机。

package com.pjb.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.util.HashMap;
import java.util.Map;


/**
 * RabbitMQ配置类
 * @author pan_junbiao
 **/
@Configuration
public class RabbitMqConfig
{
    public static final String DELAY_EXCHANGE_NAME = "delayed_exchange";
    public static final String DELAY_QUEUE_NAME = "delay_queue_name";
    public static final String DELAY_ROUTING_KEY = "delay_routing_key";

    @Bean
    public CustomExchange delayExchange()
    {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange(DELAY_EXCHANGE_NAME, "x-delayed-message", true, false, args);
    }

    @Bean
    public Queue queue()
    {
        Queue queue = new Queue(DELAY_QUEUE_NAME, true);
        return queue;
    }

    @Bean
    public Binding binding(Queue queue, CustomExchange delayExchange)
    {
        return BindingBuilder.bind(queue).to(delayExchange).with(DELAY_ROUTING_KEY).noargs();
    }
}

(4)实现消息发送

实现消息发送,这里设置消息延迟 5s。

package com.pjb.mq;

import com.pjb.config.RabbitMqConfig;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 消息发送者
 * @author pan_junbiao
 **/
@Service
public class CustomSender
{
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMsg(String msg)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("消息发送时间:" + sdf.format(new Date()));
        rabbitTemplate.convertAndSend(RabbitMqConfig.DELAY_EXCHANGE_NAME, RabbitMqConfig.DELAY_ROUTING_KEY, msg, new MessagePostProcessor()
        {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException
            {
                //消息延迟5秒
                message.getMessageProperties().setHeader("x-delay", 5000);
                return message;
            }
        });
    }
}

(5)实现消息接收

package com.pjb.mq;

import com.pjb.config.RabbitMqConfig;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 消息接收者
 * @author pan_junbiao
 **/
@Component
public class CustomReceiver
{
    @RabbitListener(queues = RabbitMqConfig.DELAY_QUEUE_NAME)
    public void receive(String msg)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(new Date())+msg);
        System.out.println("Receiver:执行取消订单");
    }
}

(6)测试发送延迟消息

package com.pjb;

import com.pjb.mq.CustomSender;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * RabbitMQ测试类
 * @author pan_junbiao
 **/
@SpringBootTest
public class MQTest
{
    @Autowired
    private CustomSender customSender;

    @Test
    public void send() throws Exception
    {
        //发送消息
        customSender.sendMsg("支付超时,取消订单通知!");

        //程序延时15秒,否则程序立即执行完毕,则控制台无法看到消息队列延迟的结果
        Thread.sleep(15000);
    }
}

执行结果:

猜你喜欢

转载自blog.csdn.net/pan_junbiao/article/details/112711560