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我们经常的使用, ...
随机推荐
- 47-python基础-python3-字符串-常用字符串方法(五)-rjust()-ljust()-center()
6-rjust().ljust()和 center()方法对齐文本 rjust()和 ljust()字符串方法返回调用它们的字符串的填充版本,默认通过插入空格来对齐文本. rjust()和 ljust ...
- addr2line探秘 [從ip讀出程式中哪行出錯]
addr2line探秘 在Linux下写C/C++程序的程序员,时常与Core Dump相见.在内存越界访问,收到不能处理的信号,除零等错误出现时,我们精心或不精心写就的程序就直接一命呜呼了,Core ...
- CentOS 6.5安装aria2(转载)
CentOS 6.5安装aria2 由于yum install aria2无法找到安装包,试了好几个源,都找不到,于是自己找了一些地址: 1.下载安装包: # wget http://ftp.tu-c ...
- Codeforces 354C 暴力 数论
题意:给你一个数组,你可以把数组中的数减少最多k,问数组中的所有数的GCD最大是多少? 思路:容易发现,GCD的上限是数组中最小的那个数,而因为最多可以减少k,及可以凑出来的余数最大是k,那么GCD的 ...
- Python--同步锁(互斥锁)、死锁(状态)、递归锁、信号量、Event对象
同步锁/互斥锁 (Lock) import time import threading def sub(): global num #在每个线程中都获取这个全局变量 #num-=1 temp=num ...
- 洛谷P1122 最大子树和 (树状dp)
题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...
- 获取FileSystem
/** * 根据配置文件获取HDFS操作对象 * 有两种方法: * 1.使用conf直接从本地获取配置文件创建HDFS对象 * 2.多用于本地没有hadoop系统,但是可以远程访问.使用给定的URI和 ...
- layui多图上传加隐藏域
我的情况是,通过layui上传图片调用后端,后端将图片上传后返回图片路径,上传成功后将图片在页面显示出来(避免用户网速不稳定,图片其实还没上传成功就进行下一步操作),然后同步每个图片增加隐藏域,最终表 ...
- Python每日一题 004
将 0001 题生成的 200 个激活码(或者优惠券)保存到 Redis 非关系型数据库中. 代码 import redis import uuid # 创建实例 r=redis.Redis(&quo ...
- Linux系统之-文件系统,桌面环境
文件系统 文件类型普通文件,目录文件,连接文件,设备与设备文件,套接字,管道 普通文件(regular file):就是一般存取的文件,由ls -al显示出来的属性中,第一个属性为 [-],例如 [- ...