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中,框架帮我们将不同的交换机划分出 ...
随机推荐
- Binding的三种方式
1 Text="{Binding Name}" Name为后台的属性 2 Text="{Binding ElementName=XXX,Path=A.B.C.D….}&q ...
- XF 绝对布局
using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation (XamlCompila ...
- 计算机网络OSI参考模型与tcp/ip四层模型
OSI参考模型--7层 1层物理层:主要定义物理设备标准,如网线的接口类型.光线的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后在转化 ...
- Thinkphp模板开放给第三方编辑权限时,如何禁止模板使用php代码
首先我要吐槽一个问题:为什么在博客园发布的文章总是被其他网站采集过去,而他们采集过去后,排名比博客园还好,比如这篇文章,我把标题复制到百度搜索,结果第一页的搜索结果全部都是采集我的,而我在博客园发布的 ...
- DJango xadmin 表头和标底设置,显示隐藏和显示
xadmin文件中的xadmin.pyfrom xadmin import views class GlobalSetting(object): site_title = "zwb" ...
- 命令行程序如何获取HINSTANCE?
main() { HINSTANCE hinst = GetModuleHandle(NULL); }
- WPF使用AForge实现Webcam预览(二)
本文主要介绍如何让摄像头预览界面的宽高比始终在16:9. 首先我们需要修改一下上一篇随笔实现的UI界面,让Grid变成一个3*3的九宫格,预览界面位于正中间.Xaml示例代码如下: <Windo ...
- QML于C++交互之信号与槽(signal&slot )
connect c++ SIGNAL with QML SLOT 简介 QML 与 C++ 混合编程时,总结了一下qml和c++互相直接调用.及信号与槽连接 的几种情况,详细使用情况看示例代码 所有的 ...
- qt开发的小软件,可以递归转换文件编码(qt为了防止内存泄露所做的保护机制)
应用场景 当你下载别人的源码的时候,而别人的源码跟你自己电脑里面的编码不一致的情况下将会出现乱码,但是如果要一个个转换编码的话那么那样所需要花的时间太多,所以就有必要写一个软件递归遍历项目下面所有的文 ...
- python中的set集合和深浅拷贝
一.基础数据类型的补充 1.str中的join算法,将列表转换成字符串,并用'_'(或其他) li=['李嘉诚','马化腾','刘嘉玲','黄海峰',] s='_'.join(li) print(s) ...