springboot使用RabbitMQ实现延时任务
延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费。
那么,为什么需要延迟消费呢?我们来看以下的场景
订单业务: 在电商/点餐中,都有下单后 30 分钟内没有付款,就自动取消订单。
短信通知: 下单成功后 60s 之后给用户发送短信通知。
失败重试: 业务操作失败后,间隔一定的时间进行失败重试。
本文基于springboot,使用rabbitmq_delayed_message_exchange插件实现延时队列(RabbitMQ及其插件环境安装点此),具体实践如下:
application.properties
spring.rabbitmq.username=root
spring.rabbitmq.password=root
spring.rabbitmq.host=192.168.1.123
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=test
XdelayConfig.java
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; @Configuration
public class XdelayConfig { /**
* 立即消费的队列名称
*/
public static final String IMMEDIATE_QUEUE_XDELAY = "queue.xdelay.immediate";
/**
* 延时的exchange
*/
public static final String DELAYED_EXCHANGE_XDELAY = "exchange.xdelay.delayed";
public static final String DELAY_ROUTING_KEY_XDELAY = "routingkey.xdelay.delay"; /**
* 创建一个立即消费队列
*
* @return
*/
@Bean
public Queue immediateQueue() {
// 第一个参数是创建的queue的名字,第二个参数是是否支持持久化
return new Queue(IMMEDIATE_QUEUE_XDELAY, true);
} @Bean
public CustomExchange delayExchange() {
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-delayed-type", "direct");
return new CustomExchange(DELAYED_EXCHANGE_XDELAY, "x-delayed-message", true, false, args);
} /**
* 把立即消费的队列和延时消费的exchange绑定在一起
*
* @return
*/
@Bean
public Binding bindingNotify() {
return BindingBuilder.bind(immediateQueue()).to(delayExchange()).with(DELAY_ROUTING_KEY_XDELAY).noargs();
}
}
XdelaySender.java 生产者
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.text.SimpleDateFormat;
import java.util.Date; /**
* 生产者
*/
@Component
public class XdelaySender {
private final static Logger logger = LoggerFactory.getLogger(XdelaySender.class);
@Autowired
private RabbitTemplate rabbitTemplate; public void send(String msg, int delayTime) {
logger.info("msg= " + msg + ".delayTime" + delayTime);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
this.rabbitTemplate.convertAndSend(XdelayConfig.DELAYED_EXCHANGE_XDELAY, XdelayConfig.DELAY_ROUTING_KEY_XDELAY, msg, message -> {
message.getMessageProperties().setDelay(delayTime);
System.out.println(sdf.format(new Date()) + " Delay sent.");
return message;
});
}
}
XdelayReceiver.java 消费者
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import java.text.SimpleDateFormat;
import java.util.Date; /**
* 消费者
*/
@Component
@EnableRabbit
@Configuration
public class XdelayReceiver {
private final static Logger logger = LoggerFactory.getLogger(XdelayReceiver.class); @RabbitListener(queues = com.example.antchat.rabbitmq.XdelayConfig.IMMEDIATE_QUEUE_XDELAY)
public void get(String msg) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
logger.info("收到延时消息时间:" + sdf.format(new Date()) + " Delay sent.");
logger.info("收到延时消息:" + msg);
}
}
测试
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class RabbitMQController {
@Autowired
XdelaySender xdelaySender;
@RequestMapping("/testRabbit")
public void testRabbit() {
xdelaySender.send("我来发一个测试消息,10秒", 10000);//10秒
xdelaySender.send("我来发一个测试消息,2秒", 2000);//2秒
xdelaySender.send("我来发一个测试消息,1秒", 2000);//1秒
}
}
参考博文:
微服务-springboot-rabbitmq:实现延时队列
springboot使用RabbitMQ实现延时任务的更多相关文章
- SpringBoot集成RabbitMQ
官方说明:http://www.rabbitmq.com/getstarted.html 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ ...
- SpringBoot集成rabbitmq(二)
前言 在使用rabbitmq时,我们可以通过消息持久化来解决服务器因异常崩溃而造成的消息丢失.除此之外,我们还会遇到一个问题,当消息生产者发消息发送出去后,消息到底有没有正确到达服务器呢?如果不进行特 ...
- SpringBoot之RabbitMQ的使用
一 .RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件,消息中间件的工作过程可以用生产者消费者模型来表示.即,生产者不断的向消息队列发 ...
- SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门
1.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.Rabbi ...
- Spring-boot之 rabbitmq
今天学习了下spring-boot接入rabbitmq. windows下的安装:https://www.cnblogs.com/ericli-ericli/p/5902270.html 使用博客:h ...
- springboot学习笔记-6 springboot整合RabbitMQ
一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...
- 【SpringBoot系列5】SpringBoot整合RabbitMQ
前言: 因为项目需要用到RabbitMQ,前几天就看了看RabbitMQ的知识,记录下SpringBoot整合RabbitMQ的过程. 给出两个网址: RabbitMQ官方教程:http://www. ...
- SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...
- rabbitmq学习(五):springboot整合rabbitmq
一.Springboot对rabbitmq的支持 springboot提供了对rabbitmq的支持,并且大大简化了rabbitmq的相关配置.在springboot中,框架帮我们将不同的交换机划分出 ...
随机推荐
- [数字dp] hdu 3271 SNIBB
意甲冠军:有两个查询: q=1.在[x,y]间隔,兑换b十进制,数字和m多少个月. q=2.在[x,y]间隔,兑换b十进制,数字是m第一k的数目是多少(十进制),没有输出由给定的主题. 思维: 和比特 ...
- NoSQL Manager for MongoDB 4.6.0.3 带key
NoSQL Manager for MongoDB 4.6.0.3 是一个Windows平台的MongoDB高级管理工具.请低调使用. 博客园文件一次最大不超过10M. 官方安装包: mongodbm ...
- Win8Metro(C#)数字图像处理--2.8图像线性变换
原文:Win8Metro(C#)数字图像处理--2.8图像线性变换 2.8图像线性变换 [函数名称] 图像线性变换函数LinearTransformProcess(WriteableBitmap ...
- SQL之连接查询
这几天忙着笔试.面试,遇到了好几个关于数据库的试题,当然只是简单的多表查询.我第一时间都是选择select...from...where...group by...having...这个结构去写的.但 ...
- PopupWindow设置动画效果
创建popupwindow的方法 Button menu; private void showPopupWindow() { //设置contentView float density = Densi ...
- UWP入门(五)--控件模板
原文:UWP入门(五)--控件模板 通过在 XAML 框架中创建控件模板,你可以自定义控件的可视结构和可视行为(eg:勾选框的三种状态). 控件有多个属性,如 Background.Foregroun ...
- extjs grid 复选框选择事件
开发中需求是统计选择的行数,所以要监控checkbox的选择事件包括表头的全选事件 遇到的问题就不赘述了 方案是监控grid的复选框和行加载时绑定事件 baseView: DBEN.controls. ...
- windows和linux双系统,重新分区后修复grub
我电脑里装的是 windows 7 profressional 和 fedora 12 ,本来给 C 盘分了 50G ,原本以为够了,结果50G 瞬间用完,于是乎开始重新分区. PQ 是不能用了,上网 ...
- DataSet与JSON互转
DataSetConverter4Delphi https://github.com/ezequieljuliano/DataSetConverter4Delphi ----------------- ...
- std::string的Copy-on-Write:不如想象中美好(VC不使用这种方式,而使用对小字符串更友好的SSO实现)
Copy-on-write(以下简称COW)是一种很重要的优化手段.它的核心思想是懒惰处理多个实体的资源请求,在多个实体之间共享某些资源,直到有实体需要对资源进行修改时,才真正为该实体分配私有的资源. ...