RabbitMQ延迟队列(重要)

RabbitMQ延迟队列

1、延迟队列

https://blog.csdn.net/weixin_42942786/article/details/139940269

1.1、延迟队列使用场景

场景:有一个订单,15分钟内如果不支付,就把该订单设置为交易关闭,那么就不能支付了,这类实现延迟任务的场景就可以采用延迟队列来实现,当然除了延迟队列来实现,也可以有一些其他办法实现;

1.2、延迟队列实现原理

RabbitMQ本身不支持延迟队列,可以使用TTL(过期消息)结合DLX(死信交换机)的方式来实现消息的延迟投递,即把DLX(死信交换机)跟某个队列绑定,到了指定时间,消息过期后,就会从DLX(死信交换机)路由到这个队列,消费者可以从这个队列取走消息。

2、使用rabbitmq-delayed-message-exchange 延迟插件

2.1、下载

选择对应的版本下载 rabbitmq-delayed-message-exchange 插件,

下载地址:http://www.rabbitmq.com/community-plugins.html


2.2、安装

插件拷贝到 RabbitMQ 服务器plugins目录下

2.2.1、解压

java 复制代码
unzip rabbitmq_delayed_message_exchange-3.10.2.ez

如果unzip 没有安装,先安装一下

java 复制代码
yum install unzip -y

2.2.2、启用插件

java 复制代码
./rabbitmq-plugins enable rabbitmq_delayed_message_exchange 开启插件;

2.2.3、查询安装情况

./rabbitmq-plugins list 查询安装的所有插件;

重启rabbitmq使其生效;(此处也可以不重启)

消息发送后不会直接投递到队列,

而是存储到 Mnesia(嵌入式数据库),检查 x-delay 时间(消息头部);

延迟插件在 RabbitMQ 3.5.7 及以上的版本才支持,依赖 Erlang/OPT 18.0 及以上运行环境;

Mnesia 是一个小型数据库,不适合于大量延迟消息的实现

解决了消息过期时间不一致出现的问题。

2.4、示例

2.4.1、RabbitConfig配置类(关键代码)

java 复制代码
package com.power.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class RabbitConfig {

    @Value("${my.exchangeName}")
    private String exchangeName;

    @Value("${my.queueDelayName}")
    private String queueDelayName;

    //创建自定义交换机
    @Bean
    public CustomExchange customExchange() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-delayed-type","direct");
        return new CustomExchange(exchangeName,"x-delayed-message",true,false,arguments);
    }

    //创建队列
    @Bean
    public Queue queueNormal() {
        //建造者模式创建队列
        return QueueBuilder
                .durable(queueDelayName)//队列名称
                .build();
    }

    //队列绑定交换机
    @Bean
    public Binding binding(CustomExchange customExchange, Queue queueNormal) {
        return BindingBuilder.bind(queueNormal).to(customExchange).with("plugin").noargs();
    }

}

2.4.2、发送消息(关键代码)

java 复制代码
package com.power.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

@Service
@Slf4j
public class MessageService {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Bean
    public void sendMsg(){
        {
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setHeader("x-delay",25000);//第一条消息设置过期时间25秒
            Message message = MessageBuilder.withBody("hello world 01".getBytes())
                    .andProperties(messageProperties)
                    .build();
            rabbitTemplate.convertAndSend("exchange.delay.04","plugin",message);
            log.info("消息order发送完毕,发送时间是:{}",new Date());
        }
        {
            MessageProperties messageProperties = new MessageProperties();
            messageProperties.setHeader("x-delay",15000);//第二条消息设置过期时间15秒
            Message message = MessageBuilder.withBody("hello world 02".getBytes())
                    .andProperties(messageProperties)
                    .build();
            rabbitTemplate.convertAndSend("exchange.delay.04","plugin",message);
            log.info("消息pay发送完毕,发送时间是:{}",new Date());
        }

    }
}

2.4.3、application.yml配置类

java 复制代码
server:
  port: 8080
spring:
  application:
    name: delay-plugins-test01

  rabbitmq:
    host: 你的服务器IP
    port: 5672
    username: 你的账号
    password: 你的密码
    virtual-host: power

my:
  exchangeName: exchange.delay.04         # 交换机
  queueDelayName: queue.delay.04          # 正常队列

2.4.4、接收消息

java 复制代码
package com.power.message;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Slf4j
public class ReceiveMessage {
    @RabbitListener(queues = "queue.delay.04")
    public void receiveMsg(Message message){
        String body = new String(message.getBody());
        log.info("接收到的消息为:{},接收时间为:{}",body,new Date());
    }
}

2.4.5、pom.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.power</groupId>
  <artifactId>rabbit_07_delay04_plugins</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>rabbit_07_delay04_plugins</name>

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.13</version>
    <relativePath/>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

2.4.6、测试

相关推荐
꧁薄暮꧂17 分钟前
kafka是如何处理数据乱序问题
分布式·kafka
CodingBrother1 小时前
RabbitMQ高效的消息队列中间件原理及实践
中间件·rabbitmq
songqq271 小时前
【快速解决】kafka崩了,重启之后,想继续消费,怎么做?
分布式·kafka
zmd-zk1 小时前
hive中windows子句的使用
大数据·数据仓库·hive·hadoop·windows·分布式·big data
CodingBrother4 小时前
RabbitMQ 与 PHP Swoole 实现
rabbitmq·php·swoole
斑驳竹影9 小时前
【RabbitMQ】之高可用集群搭建
分布式·rabbitmq
P.H. Infinity9 小时前
【RabbitMQ】07-业务幂等处理
java·rabbitmq·java-rabbitmq
floret*10 小时前
Kafka高频面试题详解
分布式·kafka
Wlq041510 小时前
分布式技术缓存技术
分布式·缓存
明达技术11 小时前
LVDS高速背板总线:打造分布式I/O高效数据传输新境界
分布式·物联网·自动化·lvds