RabbitMQ 如何实现延迟队列?
延迟队列是指当消息被发送以后,并不是立即执行,而是等待特定的时间后,消费者才会执行该消息。
延迟队列的使用场景有以下几种:
- 未按时支付的订单,30 分钟过期之后取消订单。
- 给活跃度比较低的用户间隔 N 天之后推送消息,提高活跃度。
- 新注册会员的用户,等待几分钟之后发送欢迎邮件等。
1.如何实现延迟队列?
延迟队列有以下两种实现方式:
- 通过消息过期后进入死信交换器,再由交换器转发到延迟消费队列,实现延迟功能;
- 使用官方提供的延迟插件实现延迟功能。
早期,大部分公司都会采用第一种方式,而随着 RabbitMQ 3.5.7(2015 年底发布)的延迟插件的发布,因为其使用更简单、更方便,所以它现在才是大家普通会采用的,实现延迟队列的方式,所以本文也只讲第二种方式。
2.实现延迟队列
2.1 安装并启动延迟队列
2.1.1 下载延迟插件
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases
注意:需要根据你自己的 RabbitMQ 服务器端版本选择相同版本的延迟插件,可以在 RabbitMQ 控制台查看:


2.1.2 将插件放到插件目录
接下来,将上一步下载的插件放到 RabbitMQ 服务器安装目录,如果是 docker,使用一下命令复制:
docker cp 宿主机文件 容器名称或ID:容器目录
如下图所示:

之后,进入 docker 容器,查看插件中是否包含延迟队列:
docker exec -it 容器名称或ID /bin/bash
rabbitmq-plugins list
如下图所示:

2.1.3 启动插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
如下图所示:

2.1.4 重启RabbitMQ服务
安装完 RabbitMQ 插件之后,需要重启 RabbitMQ 服务才能生效。
如果使用的是 Docker,只需要重启 Docker 容器即可:
docker restart 容器名称或ID
如下图所示:

2.1.5 验收结果
在 RabbitMQ 控制台查看,新建交换机时是否有延迟消息选项,如果有就说明延迟消息插件已经正常运行了,如下图所示:

2.1.6 手动创建延迟交换器(可选)
此步骤可选(非必须),因为某些版本下通过程序创建延迟交换器可能会出错,如果出错了,手动创建延迟队列即可,如下图所示:

2.2 编写延迟消息实现代码
2.2.1 配置交换器和队列
import org.springframework.context.annotation.Configuration;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
/**
* 延迟交换器和队列
*/
@Configuration
public class DelayedExchangeConfig {
public static final String EXCHANGE_NAME = "myDelayedExchange";
public static final String QUEUE_NAME = "delayed.queue";
public static final String ROUTING_KEY = "delayed.routing.key";
@Bean
public CustomExchange delayedExchange() {
return new CustomExchange(EXCHANGE_NAME,
"x-delayed-message", // 消息类型
true, // 是否持久化
false); // 是否自动删除
}
@Bean
public Queue delayedQueue() {
return QueueBuilder.durable(QUEUE_NAME)
.withArgument("x-delayed-type", "direct")
.build();
}
@Bean
public Binding delayedBinding(Queue delayedQueue,CustomExchange delayedExchange) {
return BindingBuilder.bind(delayedQueue()).to(delayedExchange()).with(ROUTING_KEY).noargs();
}
}
2.1.2 定义消息发送方法
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class DelayedMessageProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
@Scheduled(fixedDelay = 5000)
public void sendDelayedMessage(String message) {
rabbitTemplate.convertAndSend(DelayedExchangeConfig.EXCHANGE_NAME,
DelayedExchangeConfig.ROUTING_KEY,
message,
messagePostProcessor -> {
messagePostProcessor.getMessageProperties().setDelay(10000); // 设置延迟时间,单位毫秒
return messagePostProcessor;
});
}
}
2.1.3 发送延迟消息
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/delayed")
public class DelayedMessageController {
@Autowired
private DelayedMessageProducer delayedMessageProducer;
@GetMapping("/send")
public String sendDirectMessage(@RequestParam String message) {
delayedMessageProducer.sendDelayedMessage(message);
return "Delayed message sent to Exchange: " + message;
}
}
2.1.4 接收延迟消息
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class DelayedMessageConsumer {
@RabbitListener(queues = DelayedExchangeConfig.QUEUE_NAME)
public void receiveDelayedMessage(String message) {
System.out.println("Received delayed message: " + message);
}
}
PS:获取本文延迟队列的实现 Demo,请加我:GG_Stone【备注:延迟队列】
小结
实现 RabbitMQ 延迟队列目前主流的实现方式,是采用官方提供的延迟插件来实现。而延迟插件需要先下载插件、然后配置并重启 RabbitMQ 服务,之后就可以通过编写代码的方式实现延迟队列了。
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。
RabbitMQ 如何实现延迟队列?的更多相关文章
- SpringBoot | 第三十八章:基于RabbitMQ实现消息延迟队列方案
前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...
- RabbitMQ如何实现延迟队列?(转)
什么是延迟队列 延迟队列存储的对象肯定是对应的延迟消息,所谓"延迟消息"是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 场景一 ...
- C# RabbitMQ延迟队列功能实战项目演练
一.需求背景 当用户在商城上进行下单支付,我们假设如果8小时没有进行支付,那么就后台自动对该笔交易的状态修改为订单关闭取消,同时给用户发送一份邮件提醒.那么我们应用程序如何实现这样的需求场景呢?在之前 ...
- 【RabbitMQ】一文带你搞定RabbitMQ延迟队列
本文口味:鱼香肉丝 预计阅读:10分钟 一.说明 在上一篇中,介绍了RabbitMQ中的死信队列是什么,何时使用以及如何使用RabbitMQ的死信队列.相信通过上一篇的学习,对于死信队列已经有了更 ...
- 消息队列RabbitMQ(五):死信队列与延迟队列
死信队列 引言 死信队列,英文缩写:DLX .Dead Letter Exchange(死信交换机),其实应该叫做死信交换机才更恰当. 当消息成为Dead message后,可以被重新发送到另一个交换 ...
- RabbitMQ进阶使用-延时队列的配置(Spring Boot)
依赖 MAVEN配置pom.xml <dependency> <groupId>org.springframework.boot</groupId> <art ...
- C#实现rabbitmq 延迟队列功能
最近在研究rabbitmq,项目中有这样一个场景:在用户要支付订单的时候,如果超过30分钟未支付,会把订单关掉.当然我们可以做一个定时任务,每个一段时间来扫描未支付的订单,如果该订单超过支付时间就关闭 ...
- Spring Boot(十四)RabbitMQ延迟队列
一.前言 延迟队列的使用场景:1.未按时支付的订单,30分钟过期之后取消订单:2.给活跃度比较低的用户间隔N天之后推送消息,提高活跃度:3.过1分钟给新注册会员的用户,发送注册邮件等. 实现延迟队列的 ...
- rabbitmq延迟队列demo
1. demo详解 1.1 工程结构: 1.2 pom 定义jar包依赖的版本.版本很重要,rabbit依赖spring,两者必须相一致,否则报错: <properties> <sp ...
- Spring RabbitMQ 延迟队列
一.说明 在实际业务场景中可能会用到延时消息发送,例如异步回调失败时的重发机制. RabbitMQ本身不具有延时消息队列的功能,但是可以通过rabbitmq-delayed-message-excha ...
随机推荐
- 蓝桥杯真题 平面切分(Set自定义去重)
题目详情 资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 平面上有 N 条直线,其中第 i 条直线是 y=Ai⋅ ...
- Github疯传!谷歌师兄的LeetCode刷题笔记开源了!
有小伙伴私聊我说刚开始刷LeetCode的时候,感到很吃力,刷题效率很低.我以前刷题的时候也遇到这个问题,直到后来看到这个谷歌师兄总结的刷题笔记,发现LeetCode刷题都是套路呀,掌握这些套路之后, ...
- 技术招聘漫谈 | 正在招Golang工程师的你,赶快收藏这份识人秘籍!
各位技术面试官,欢迎来到新一期的技术招聘漫谈专栏. 在前两期的专栏中,我们解析了前端工程师以及 Java 工程师 这两个常见技术岗位的招聘技巧. 今天,我们想把目光聚焦在一个前景与"钱&qu ...
- 魔力屏障 (magic) 题解
魔力屏障 (magic) [问题描述] 小 Z 生活在神奇的魔法大陆上.今天他的魔法老师给了它这样一个法阵作为它 的期末考试题目: 法阵由从左至右 n 道魔力屏障组成,每道屏障有一个临界值 a,如果它 ...
- 使用镜像加速 Rtools 下载与安装
在 windows 使用 R,尤其是安装 R 包的时候,经常会遇到一些 Rtools 的问题,今天聊一下. Rtools 是什么 Rtools 作用很大,但我们一般不怎么会直接使用. Rtools p ...
- 驱动开发:内核扫描SSDT挂钩状态
在笔者上一篇文章<驱动开发:内核实现SSDT挂钩与摘钩>中介绍了如何对SSDT函数进行Hook挂钩与摘钩的,本章将继续实现一个新功能,如何检测SSDT函数是否挂钩,要实现检测挂钩状态有两种 ...
- C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609
C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609 环境说明: .NET Framework 4.6 的控制台程序 . .NET Framework 对于RSA的支 ...
- Pinot2的无人机任务和数据处理实践
目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 4. 应用示例与代码实现讲解 4.1 应用场景介绍 4.2 应用实例分析 ...
- JAVA 环境搭建(java 8为例)
JAVA 环境搭建 下载JDK(java 8为例) JDK下载地址:直达 JDK镜像网站: 编程宝库 java jdk镜像 安装JDK(java 8为例) 双击启动下载的exe文件 单击下一步 可以选 ...
- Kotlin 常用语法糖记录
原文地址: Kotlin 常用语法糖记录 - Stars-One的杂货小窝 当使用 Kotlin 编程时,有一些常用的函数可以帮助我们简化代码并提高开发效率. 稍微列举下常用的方法 runCatchi ...