1、需要用到插件 rabbitmq_delayed_message_exchange 来实现,插件下载地址:https://www.rabbitmq.com/community-plugins.html

2、下载后把插件放到 plugins 里面,然后到 sbin里面打开cmd,执行 rabbitmq-plugins enable rabbitmq_delayed_message_exchange 命令

3、插件装好后,重新启动mq,然后集成mq。

  首先,导包

    <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

  

  然后,配置文件配置连接信息:

spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.listener.simple.acknowledge-mode=manual

  

  mq 配置:

  

package com.rrg.gz.mq;

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; /**
* mq配置
* @author huangsz 2019/4/25 0025
*/
@Configuration
public class RabbitPluginConfig { /**
* 延时队列交换机
* 注意这里的交换机类型:CustomExchange
* @return
*/
@Bean
public CustomExchange delayExchange(){
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange("rrg_delay_exchange","x-delayed-message",true, false,args);
} /**
* 延时队列
* @return
*/
@Bean
public Queue delayQueue(){
return new Queue("rrg_delay_queue",true);
} /**
* 给延时队列绑定交换机
* @return
*/
@Bean
public Binding cfgDelayBinding(Queue cfgDelayQueue, CustomExchange cfgUserDelayExchange){
return BindingBuilder.bind(cfgDelayQueue).to(cfgUserDelayExchange).with("rrg_delay_key").noargs();
}
}

  发送消息类、接收类和信息类,信息类是我们自己时间业务封装需要消费的信息。

package com.rrg.gz.mq;

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; /**
* 消息发送者
*
* @author huangsz 2019/3/7 0007
*/
@Component
public class Sender {
private static Logger log = LoggerFactory.getLogger(Sender.class); @Autowired
private RabbitTemplate rabbitTemplate; public void sendDelayMessage(MqEntity entity, long time) {
// 这里的消息可以是任意对象,无需额外配置,直接传即可
log.info("延时队列生产消息");
this.rabbitTemplate.convertAndSend(
"rrg_delay_exchange",
"rrg_delay_key",
entity,
message -> {
// 注意这里时间可以使long,而且是设置header
message.getMessageProperties().setHeader("x-delay",time);
return message;
}
);
log.info("{}ms后执行", time);
} }
package com.rrg.gz.mq;

import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
* 接受者
*
* @author huangsz 2019/3/7 0007
*/ @Component
public class Receiver {
private static Logger log = LoggerFactory.getLogger(Receiver.class);
@Autowired
private Sender sender; @RabbitListener(queues = "rrg_delay_queue")
public void cfgUserReceiveDealy(MqEntity entity, Message message, Channel channel) throws Exception{
log.info("开始接受消息!");
// 通知 MQ 消息已被接收,可以ACK(从队列中删除)了
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
System.out.println("接收消息并打印");
System.out.println(entity);
}
}
package com.rrg.gz.mq;

import java.io.Serializable;

/**
* 一定要实现 Serializable
* @author huangsz 2019/3/7 0007
*/
public class MqEntity implements Serializable { private Integer userId;
private String msg; public MqEntity() {
} public MqEntity(Integer userId, String msg) {
this.userId = userId;
this.msg = msg;
} public Integer getUserId() {
return userId;
} public void setUserId(Integer userId) {
this.userId = userId;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} @Override
public String toString() {
return "MqEntity{" +
"userId=" + userId +
", msg='" + msg + '\'' +
'}';
}
}

4、写一个controller测试:

  

@RequestMapping("/test1")
public void test(){
MqEntity mqEntity = new MqEntity(1,"30秒后消费");
sender.sendDelayMessage(mqEntity,30000);
} @RequestMapping("/test2")
public void test2(){
MqEntity mqEntity = new MqEntity(1,"10秒后消费");
sender.sendDelayMessage(mqEntity,10000);
}

先执行test1,然后执行test2,这个时候,不需要等test1消费完之后,test2才消费信息。

Rabbitmq 实现延时任务的更多相关文章

  1. RabbitMQ实现延时消息的两种方法

    目录 RabbitMQ实现延时消息的两种方法 1.死信队列 1.1消息什么时候变为死信(dead-letter) 1.2死信队列的原理 1.3 代码实现 1.4死信队列的一个小坑 2 .延时插件 2. ...

  2. rabbitmq实现延时队列(死信队列)

    基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ...

  3. spring boot Rabbitmq集成,延时消息队列实现

    本篇主要记录Spring boot 集成Rabbitmq,分为两部分, 第一部分为创建普通消息队列, 第二部分为延时消息队列实现: spring boot提供对mq消息队列支持amqp相关包,引入即可 ...

  4. 基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景

    前言 传统处理超时订单 采取定时任务轮训数据库订单,并且批量处理.其弊端也是显而易见的:对服务器.数据库性会有很大的要求,并且当处理大量订单起来会很力不从心,而且实时性也不是特别好 当然传统的手法还可 ...

  5. springboot使用RabbitMQ实现延时任务

    延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费.那么,为什么需要延迟消费呢?我们来看以下的场景 订单业务: 在电商/点餐中,都有下单后 30 分钟内没有付款 ...

  6. rabbitMq实现延时队列

    原文:https://my.oschina.net/u/3266761/blog/1926588 rabbitMq是受欢迎的消息中间件之一,相比其他的消息中间件,具有高并发的特性(天生具备高并发高可用 ...

  7. RabbitMq 实现延时队列-Springboot版本

    rabbitmq本身没有实现延时队列,但是可以通过死信队列机制,自己实现延时队列: 原理:当队列中的消息超时成为死信后,会把消息死信重新发送到配置好的交换机中,然后分发到真实的消费队列: 步骤: 1. ...

  8. Rabbitmq的延时队列的使用

    配置: spring: rabbitmq: addresses: connection-timeout: username: guest password: guest publisher-confi ...

  9. RabbitMQ及延时队列

    一.简介 我用过RabbirMQ的发布订阅模式,以及一对一的延迟队列. 1.RabbitMQ的有消息确认机制,消费一条则队列中少一条,也有对应的消费到消息及认为是消费成功这样的模式,一般使用前者. 发 ...

随机推荐

  1. matlab练习程序(图像投影到点云)

    最近接触点云比较多,如果把图像投影到点云应该挺有意思. 首先需要载入图像,然后做个球或其他什么形状的点云,这里可以参考球坐标公式. 最后通过pcshow将像素输出到点云上即可. 原图: 投影后的点云: ...

  2. 打造IP代理池,Python爬取Boss直聘,帮你获取全国各类职业薪酬榜

    爬虫面临的问题 不再是单纯的数据一把抓 多数的网站还是请求来了,一把将所有数据塞进去返回,但现在更多的网站使用数据的异步加载,爬虫不再像之前那么方便 很多人说js异步加载与数据解析,爬虫可以做到啊,恩 ...

  3. attention 汇总(持续)

    Seq2seq Attention Normal Attention 1.  在decoder端,encoder state要进行一个线性变换,得到r1,可以用全连接,可以用conv,取决于自己,这里 ...

  4. oracle学习笔记(十六) PL/SQL 异常和goto语句

    PL/SQL 异常和goto语句 异常 预定义异常 oracle常见预定义异常: 错误号 异常错误信息名称 说明 ORA-0001 DUP_VAL_ON_INDEX 试图破坏一个唯一性限制 ORA-0 ...

  5. EF框架访问access数据库入门(后附官方推荐“驱动”版本)

    vs2017调试通过. 1.添加需要的provider,有点添加驱动的意思.右击项目,NUGET “浏览”,“JetEntityFrameworkProvider”,安装,如图 完成后配置文件(控制台 ...

  6. C# WinForm实现禁止最大化、最小化、双击标题栏、双击图标等操作

    protected override void WndProc(ref Message m) { if (m.Msg==0x112) { switch ((int) m.WParam) { //禁止双 ...

  7. django中're_path'的用法

    1.re_path和path的作用是一样的.只不过're_path'是在写url的时候可以用正则表达式,功能更加强大.2.写正则表达式都推荐使用原生字符串.也就是以‘r’开头的字符串:r'move/' ...

  8. Vue中computed和watch的区别

    在vue中computed和watch的真正区别是:computed产生于它的依赖,而watch产生于它的依赖的变化.只要依赖存在,我们就能访问到其对应的computed属性:但只有依赖发生了改变,我 ...

  9. Java基础—面向对象的三大特性

    面向对象有三大特性分别是继承.封装和多态. (1)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类 ...

  10. JavaWeb之Cookie&Session

    Cookie 直译是:小饼干.实际上,Cookie就是由服务器给客户端,并且存储在客户端上的一份小数据 应用场景 自动登录,查看浏览记录,购物车 Cookie存在的意义 HTTP请求是无状态的,客户端 ...