Rabbitmq的延时队列的使用
配置:
spring: rabbitmq: addresses: connection-timeout: username: guest password: guest publisher-confirms: true publisher-returns: true
依赖:
<!--rabbitmq --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId></dependency>
配置类:
package com.jds.rabbitmq; import com.jds.common.constant.QueueEnum; import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; @Configuration public class MQConfig { public static final String RBA_QUEUE = "rba.queue"; /* public static final String QUEUE = "queue"; public static final String TOPIC_QUEUE1 = "topic.queue1"; public static final String TOPIC_QUEUE2 = "topic.queue2"; public static final String HEADER_QUEUE = "header.queue"; public static final String TOPIC_EXCHANGE = "topicExchage"; public static final String FANOUT_EXCHANGE = "fanoutxchage"; public static final String HEADERS_EXCHANGE = "headersExchage"; *//** * Direct模式 交换机Exchange * *//* @Bean public Queue queue() { return new Queue(QUEUE, true); } *//** * Topic模式 交换机Exchange * *//* @Bean public Queue topicQueue1() { return new Queue(TOPIC_QUEUE1, true); } @Bean public Queue topicQueue2() { return new Queue(TOPIC_QUEUE2, true); } @Bean public TopicExchange topicExchage(){ return new TopicExchange(TOPIC_EXCHANGE); } @Bean public Binding topicBinding1() { return BindingBuilder.bind(topicQueue1()).to(topicExchage()).with("topic.key1"); } @Bean public Binding topicBinding2() { return BindingBuilder.bind(topicQueue2()).to(topicExchage()).with("topic.#"); } *//** * Fanout模式 交换机Exchange * *//* @Bean public FanoutExchange fanoutExchage(){ return new FanoutExchange(FANOUT_EXCHANGE); } @Bean public Binding FanoutBinding1() { return BindingBuilder.bind(topicQueue1()).to(fanoutExchage()); } @Bean public Binding FanoutBinding2() { return BindingBuilder.bind(topicQueue2()).to(fanoutExchage()); } *//** * Header模式 交换机Exchange * *//* @Bean public HeadersExchange headersExchage(){ return new HeadersExchange(HEADERS_EXCHANGE); } @Bean public Queue headerQueue1() { return new Queue(HEADER_QUEUE, true); } @Bean public Binding headerBinding() { Map<String, Object> map = new HashMap<String, Object>(); map.put("header1", "value1"); map.put("header2", "value2"); return BindingBuilder.bind(headerQueue1()).to(headersExchage()).whereAll(map).match(); }*/ /** * 订单消息实际消费队列所绑定的交换机 */ @Bean DirectExchange orderDirect() { return (DirectExchange) ExchangeBuilder .directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange()) .durable(true) .build(); } /** * 订单延迟队列队列所绑定的交换机 */ @Bean DirectExchange orderTtlDirect() { return (DirectExchange) ExchangeBuilder .directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange()) .durable(true) .build(); } /** * 订单实际消费队列 */ @Bean public Queue orderQueue() { return new Queue(QueueEnum.QUEUE_ORDER_CANCEL.getName()); } /** * 订单延迟队列(死信队列) */ @Bean public Queue orderTtlQueue() { return QueueBuilder .durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName()) .withArgument("x-dead-letter-exchange", QueueEnum.QUEUE_ORDER_CANCEL.getExchange())//到期后转发的交换机 .withArgument("x-dead-letter-routing-key", QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey())//到期后转发的路由键 .build(); } /** * 将订单队列绑定到交换机 */ @Bean Binding orderBinding(DirectExchange orderDirect,Queue orderQueue){ return BindingBuilder .bind(orderQueue) .to(orderDirect) .with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey()); } /** * 将订单延迟队列绑定到交换机 */ @Bean Binding orderTtlBinding(DirectExchange orderTtlDirect,Queue orderTtlQueue){ return BindingBuilder .bind(orderTtlQueue) .to(orderTtlDirect) .with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey()); } }
发送者:
package com.jds.rabbitmq; /** * @program: red-bag-activity->CancelOrderSender * @description: * @author: cxy * @create: 2019-12-20 17:57 **/ import com.jds.common.constant.QueueEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.AmqpException; import org.springframework.amqp.core.AmqpTemplate; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessagePostProcessor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 取消订单消息的发出者 * */ @Component public class CancelOrderSender { private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderSender.class); @Autowired private AmqpTemplate amqpTemplate; public void sendMessage(Long orderId,final long delayTimes){ //给延迟队列发送消息 amqpTemplate.convertAndSend(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange(), QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey(), orderId, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { //给消息设置延迟毫秒值 message.getMessageProperties().setExpiration(String.valueOf(delayTimes)); return message; } }); LOGGER.info("send delay message orderId:{}",orderId); } }
接受者:
package com.jds.rabbitmq; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 取消订单消息的处理 */ @Component @RabbitListener(queues = "mall.order.cancel") public class CancelOrderReceiver { private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderReceiver.class); @RabbitHandler public void handle(Long orderId){ System.err.println(System.currentTimeMillis()); LOGGER.info("receive delay message orderId:{}",orderId); System.err.println(System.currentTimeMillis()); System.err.println(orderId); System.out.println("大傻逼222222"); } }
配置调用类:
package com.jds.controller; import com.jds.rabbitmq.CancelOrderSender; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @program: red-bag-activity->DelayQController * @description: * @author: cxy * @create: 2019-12-20 18:00 **/ @RestController public class DelayQController { @Autowired CancelOrderSender cancelOrderSender; @RequestMapping(value = "/id", method = RequestMethod.GET) @ResponseBody public void detail() { * ; //发送延迟消息 cancelOrderSender.sendMessage(12333333L, delayTimes); System.out.println(12333333L); System.err.println(delayTimes); System.out.println(System.currentTimeMillis()); System.out.println(" 大傻逼"); } }
测试结果:
-- ::-exec-] com.jds.rabbitmq.CancelOrderSender [] -| send delay message orderId: 大傻逼 -- ::-] com.jds.rabbitmq.CancelOrderReceiver [] -| receive delay message orderId: 大傻逼222222
调用:
http://localhost:8082/id,可以看到时间会延迟三秒。
实现主要地方:
new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { //给消息设置延迟毫秒值 message.getMessageProperties().setExpiration(String.valueOf(delayTimes)); return message; }
给参数设置延迟时间
Rabbitmq的延时队列的使用的更多相关文章
- 基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景
前言 传统处理超时订单 采取定时任务轮训数据库订单,并且批量处理.其弊端也是显而易见的:对服务器.数据库性会有很大的要求,并且当处理大量订单起来会很力不从心,而且实时性也不是特别好 当然传统的手法还可 ...
- rabbitMq实现延时队列
原文:https://my.oschina.net/u/3266761/blog/1926588 rabbitMq是受欢迎的消息中间件之一,相比其他的消息中间件,具有高并发的特性(天生具备高并发高可用 ...
- RabbitMq 实现延时队列-Springboot版本
rabbitmq本身没有实现延时队列,但是可以通过死信队列机制,自己实现延时队列: 原理:当队列中的消息超时成为死信后,会把消息死信重新发送到配置好的交换机中,然后分发到真实的消费队列: 步骤: 1. ...
- 【日常摘要】- RabbitMq实现延时队列
简介 什么是延时队列? 一种带有延迟功能的消息队列 过程: 使用场景 比如存在某个业务场景 发起一个订单,但是处于未支付的状态?如何及时的关闭订单并退还库存? 如何定期检查处于退款订单是否已经成功退款 ...
- rabbitmq实现延时队列(死信队列)
基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ...
- RabbitMQ及延时队列
一.简介 我用过RabbirMQ的发布订阅模式,以及一对一的延迟队列. 1.RabbitMQ的有消息确认机制,消费一条则队列中少一条,也有对应的消费到消息及认为是消费成功这样的模式,一般使用前者. 发 ...
- rabbitmq 安装延时队列插件rabbitmq-delayed-message-exchange
1.下载rabbitmq-delayed-message-exchange(注意版本对应) 链接:https://github.com/rabbitmq/rabbitmq-delayed-messag ...
- IOS IAP 自动续订 之 利用rabbitmq延时队列自动轮询检查是否续订成功
启用针对自动续期订阅的服务器通知: - 官方地址: - https://help.apple.com/app-store-connect/#/dev0067a330b - 相关字段, 相关类型地址: ...
- 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...
随机推荐
- 逃脱 (简单BFS)
题目传送门 G逃脱 题目描述 这是mengxiang000和Tabris来到幼儿园的第四天,幼儿园老师在值班的时候突然发现幼儿园某处发生火灾,而且火势蔓延极快,老师在第一时间就发出了警报,位于幼儿园 ...
- kubernetes(k8s)容器集群管理
Kubernetes介绍 Kubernetes是google在2014年6月开源的一个容器集群管理系统,使用go语言开发,Kubernetes也称k8s. k8s是google内部一个叫borg的容器 ...
- Docker基础(上)
Docker基础(上) 链接:https://pan.baidu.com/s/1KQjKml2OZAReYwOvpWD9XQ 提取码:6vo8 复制这段内容后打开百度网盘手机App,操作更方便哦 1. ...
- 使用IntelliJ IDEA 15和Maven创建Java Web项目(转)
转自:https://blog.csdn.net/myarrow/article/details/50824793 1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和 ...
- Struts2关于命名空间的例子
佐证了这样一个原则,package存在,但action没找到,就自动去默认空间去找.如果package不存在,则自动向上一级目录找,一级级倒到根目录. 根目录再没找到,再去默认目录找 网上对于命名空 ...
- js 在array的遍历操作中修改arry中元素数量 出现的一些奇特的操作
在js中array是属于复杂类型,在arr1=arr2得赋值操作中,arr1得到的值并不是arr2的value,而是一个指向引用.那么修改arr1的同时arr2读取的值也会同步变化,那么问题来了,上代 ...
- Es学习第四课, 倒排索引
大家知道,ES的发明者初衷是想做一个搜索引擎给自己老婆用来搜菜谱,所以ES的核心工作就是做搜索,下面我们就开始讲关于搜索方面的知识点. DOC的概念我们第一课就讲过,它是ES存储数据的最小单元,我们再 ...
- 阿里HBase高可用8年“抗战”回忆录
2017年开始阿里HBase走向公有云,我们有计划的在逐步将阿里内部的高可用技术提供给外部客户,目前已经上线了同城主备,将作为我们后续高可用能力发展的一个基础平台.本文分四个部分回顾阿里HBase在高 ...
- BZOJ 3653: 谈笑风生(主席树)
传送门 解题思路 首先对于一个\(a\)来说,要求\(b\)和\(c\),那么\(a,b,c\)一定在一条链上.把\(b\)分类讨论,如果\(b\)是\(a\)的祖宗,这个方案数就很好统计了,就是\( ...
- UIDatePicker odd behavior when setting minuteInterval
http://stackoverflow.com/questions/6948297/uidatepicker-odd-behavior-when-setting-minuteinterval Her ...