延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费。
那么,为什么需要延迟消费呢?我们来看以下的场景

订单业务: 在电商/点餐中,都有下单后 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实现延时任务的更多相关文章

  1. SpringBoot集成RabbitMQ

    官方说明:http://www.rabbitmq.com/getstarted.html 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.MQ ...

  2. SpringBoot集成rabbitmq(二)

    前言 在使用rabbitmq时,我们可以通过消息持久化来解决服务器因异常崩溃而造成的消息丢失.除此之外,我们还会遇到一个问题,当消息生产者发消息发送出去后,消息到底有没有正确到达服务器呢?如果不进行特 ...

  3. SpringBoot之RabbitMQ的使用

    一 .RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件,消息中间件的工作过程可以用生产者消费者模型来表示.即,生产者不断的向消息队列发 ...

  4. SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门

    1.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.Rabbi ...

  5. Spring-boot之 rabbitmq

    今天学习了下spring-boot接入rabbitmq. windows下的安装:https://www.cnblogs.com/ericli-ericli/p/5902270.html 使用博客:h ...

  6. springboot学习笔记-6 springboot整合RabbitMQ

    一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...

  7. 【SpringBoot系列5】SpringBoot整合RabbitMQ

    前言: 因为项目需要用到RabbitMQ,前几天就看了看RabbitMQ的知识,记录下SpringBoot整合RabbitMQ的过程. 给出两个网址: RabbitMQ官方教程:http://www. ...

  8. SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...

  9. rabbitmq学习(五):springboot整合rabbitmq

    一.Springboot对rabbitmq的支持 springboot提供了对rabbitmq的支持,并且大大简化了rabbitmq的相关配置.在springboot中,框架帮我们将不同的交换机划分出 ...

随机推荐

  1. Matlab随笔之三维图形绘制

    1.三维曲线 用到了plot3函数.plot3(x,y,z)用来绘制3维曲线图,而不能绘制曲面图!就是把所有的(x,y,z)点连接在一起. t=linspace(,*pi,); x=sin(t); y ...

  2. EF 导航属性的使用

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  3. String,CString,TCHAR,char之间区别和联系

    char是类型TCHAR也是!不过他可以通过是否定义了UNICODE宏来判断到底是char还是w_char; TCHAR是一种字符串类型,它让你在以MBCS和UNNICODE来build程序时可以使用 ...

  4. 【C#】wpf查找父子节点

    原文:[C#]wpf查找父子节点 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  5. Android项目实战(四十四):Zxing二维码切换横屏扫描

    原文:Android项目实战(四十四):Zxing二维码切换横屏扫描 Demo链接 默认是竖屏扫描,但是当我们在清单文件中配置横屏显示的时候: <activity android:name=&q ...

  6. iOS9 Spotlight使用

    1.Spotloight是什么? Spotlight在iOS9上做了一些新的改进, 也就是开放了一些新的API, 通过Core Spotlight Framework你可以在你的app中集成Spotl ...

  7. DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)

    DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...

  8. WPF 使用Trigger遇到的问题

    1. 在style中使用trigger无效的场景 原因是直接在对象上设置值将导致style中的值无效,去掉TextBlock对象的Foreground后,Trigger将正常工作 <TextBl ...

  9. python脚本,重新设置图片大小

    最近在做一个android的电台,此android程序要访问自己服务器上的歌曲文件,包括图片.这些文件要自己手动上传. 每天十首歌,需要二十个图片(一个大图450*450.一个小图140*140). ...

  10. Window上安装kafka

    kafka在windows上的安装.运行 - 进阶者ryan-su - CSDN博客 https://blog.csdn.net/u010283894/article/details/77106159 ...