Spring RabbitMQ 延迟队列
一、说明
在实际业务场景中可能会用到延时消息发送,例如异步回调失败时的重发机制。 RabbitMQ本身不具有延时消息队列的功能,但是可以通过rabbitmq-delayed-message-exchange来实现(也可以通过TTL(Time To Live)、DLX(Dead Letter Exchanges)特性实现,我们主要讲解通过延迟插件来实现的方法)。利用RabbitMQ的这种特性,应该可以实现很多现实中的业务,我们可以发挥想象。
二、安装插件
RabbitMQ的安装请参考我的文章“RabbitMQ安装与使用”,这里我们重点讲插件的安装。
首先到http://www.rabbitmq.com/community-plugins.html网页下载适合的“rabbitmq_delayed_message_exchange插件”。下载完成后将它放到RabbitMQ插件安装目录({rabbitmq-server}/plugins/),然后执行命令rabbitmq-plugins enable rabbitmq_delayed_message_exchange启用插件,执行命令rabbitmq-plugins disable rabbitmq_delayed_message_exchange也可以关闭插件。具体过程可以查看参考文档2。
三、spring集成RabbitMQ
1、maven配置
- <dependency>
- <groupId>org.springframework.amqp</groupId>
- <artifactId>spring-amqp</artifactId>
- <version>1.6.6.RELEASE</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.1.6.RELEASE</version>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.amqp</groupId>
- <artifactId>spring-rabbit</artifactId>
- <version>1.6.6.RELEASE</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.1.6.RELEASE</version>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-messaging</artifactId>
- <version>4.1.6.RELEASE</version>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>4.1.6.RELEASE</version>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.1.6.RELEASE</version>
- </exclusion>
- </exclusions>
- </dependency>
说明:实现延迟队列需要Spring在4.1以上,spring-amqp在1.6以上。
2、xml配置
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:rabbit="http://www.springframework.org/schema/rabbit"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
- http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.6.xsd">
- <context:property-placeholder location="classpath:rmq-config.properties" ignore-unresolvable="true"/>
- <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
- <property name="host" value="${rabbitmq.host}" />
- <property name="port" value="${rabbitmq.port}" />
- <property name="username" value="${rabbitmq.username}" />
- <property name="password" value="${rabbitmq.password}" />
- <property name="channelCacheSize" value="${rabbitmq.channel.cacheSize}" />
- </bean>
- <bean id="orderConsumer" class="com.xxx.rmq.OrderConsumer"></bean>
- <bean id="messageConverter" class="org.springframework.amqp.support.converter.SimpleMessageConverter" />
- <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />
- <rabbit:admin connection-factory="connectionFactory" />
- <!-- 延迟消息start -->
- <rabbit:topic-exchange name="delay_exchange" delayed="true">
- <rabbit:bindings>
- <rabbit:binding queue="delay_queue" pattern="order.delay.notify" />
- </rabbit:bindings>
- </rabbit:topic-exchange>
- <rabbit:queue name="delay_queue" durable="true" auto-declare="true" auto-delete="false" />
- <rabbit:template id="delayMsgTemplate" connection-factory="connectionFactory" message-converter="jsonMessageConverter" exchange="delay_exchange" />
- <rabbit:listener-container connection-factory="connectionFactory" channel-transacted="false" acknowledge="auto" message-converter="jsonMessageConverter">
- <rabbit:listener queues="delay_queue" ref="orderConsumer" method="delayMsg" />
- </rabbit:listener-container>
- <!-- 延迟消息end -->
- </beans>
说明:spring-rabbit-1.6.xsd必须是1.6及以上版本,否则会报“元素 'rabbit:topic-exchange' 中不允许出现属性 'delayed'”错误。具体请查看参考文档3。
四、延迟队列的使用
1、发送消息Producer
- import net.sf.json.JSONObject;
- import org.apache.commons.lang.StringUtils;
- 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.Service;
- /**
- *
- * @author Horace
- * @version 创建时间:2016年10月26日 下午6:34:31
- */
- @Service
- public class MessageProducerServiceImpl implements MessageProducerService{
- @Autowired
- private AmqpTemplate delayMsgTemplate;
- @Override
- public void delayMsg(JSONObject msg,int delay) {
- // TODO Auto-generated method stub
- final int xdelay= delay*1000;
- delayMsgTemplate.convertAndSend("order.delay.notify", (Object) msg,
- new MessagePostProcessor() {
- @Override
- public Message postProcessMessage(Message message)
- throws AmqpException {
- // TODO Auto-generated method stub
- message.getMessageProperties().setDelay(xdelay);
- return message;
- }
- });
- }
- }
2、异步接收消息Consumer
- import net.sf.json.JSONObject;
- import org.apache.commons.lang.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- /**
- *
- * @author Horace
- * @version 创建时间:2016年10月26日 下午2:48:14
- */
- public class OrderConsumer {
- private static Logger logger = LoggerFactory.getLogger(OrderConsumer.class);
- @Autowired
- private MessageProducerService messageProducerService;
- public void delayMsg(Object obj) {
- logger.info("[延时消息]" + obj);
- if (obj != null) {
- JSONObject notifyJson = JSONObject.fromObject(obj);
- String notifyUrl = notifyJson.getString("notifyUrl");
- String notifyContent = notifyJson.getString("notifyContent");
- String result = HttpUtil.postMessage(notifyUrl, notifyContent);
- if (StringUtils.isBlank(result)) { // 通知失败 进入重发机制
- int newNotifyCount = notifyJson.getInt("notifyCount") + 1; //已经通知的次数
- if (newNotifyCount < 5) {
- notifyJson.put("notifyCount", newNotifyCount);
- int spacingInterval = getSpacingInterval(newNotifyCount);
- messageProducerService
- .delayMsg(notifyJson, spacingInterval);
- } else {
- logger.info("通知5次都失败,等待后台手工处理!");
- }
- }
- }
- }
- /**
- * 重复通知间隔时间(单位为秒)
- * @param notifyCount 已经通知的次数
- * @return
- */
- private int getSpacingInterval(int notifyCount) {
- // TODO Auto-generated method stub
- int spacingInterval = 0;
- switch (notifyCount) {
- case 1:
- spacingInterval = 10;
- break;
- case 2:
- spacingInterval = 20;
- break;
- case 3:
- spacingInterval = 30;
- break;
- case 4:
- spacingInterval = 60;
- break;
- case 5:
- spacingInterval = 90;
- break;
- default:
- break;
- }
- return spacingInterval;
- }
- }
Spring RabbitMQ 延迟队列的更多相关文章
- C# RabbitMQ延迟队列功能实战项目演练
一.需求背景 当用户在商城上进行下单支付,我们假设如果8小时没有进行支付,那么就后台自动对该笔交易的状态修改为订单关闭取消,同时给用户发送一份邮件提醒.那么我们应用程序如何实现这样的需求场景呢?在之前 ...
- RabbitMQ延迟队列
rabbitmq延迟队列 rabbitmq实现延迟队列用了rabbitmq-delayed-message-exchange插件,需要提前安装,并启用. 原理 其原理是通过Exchange来实现延迟功 ...
- RabbitMQ延迟队列插件安装
RabbitMQ延迟队列插件安装 一.下载插件 下载地址:https://www.rabbitmq.com/community-plugins.html 二.把下载的插件放到指定位置 下载的文件为zi ...
- Spring Boot (26) RabbitMQ延迟队列
延迟消息就是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 延迟队列 订单业务: 在电商/点餐中,都有下单后30分钟内没有付款,就自动取消订单. 短 ...
- Spring Boot(十四)RabbitMQ延迟队列
一.前言 延迟队列的使用场景:1.未按时支付的订单,30分钟过期之后取消订单:2.给活跃度比较低的用户间隔N天之后推送消息,提高活跃度:3.过1分钟给新注册会员的用户,发送注册邮件等. 实现延迟队列的 ...
- rabbitmq延迟队列demo
1. demo详解 1.1 工程结构: 1.2 pom 定义jar包依赖的版本.版本很重要,rabbit依赖spring,两者必须相一致,否则报错: <properties> <sp ...
- RabbitMQ 延迟队列,消息延迟推送
目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...
- SpringBoot RabbitMQ 延迟队列代码实现
场景 用户下单后,如果30min未支付,则删除该订单,这时候就要可以用延迟队列 准备 利用rabbitmq_delayed_message_exchange插件: 首先下载该插件:https://ww ...
- C#实现rabbitmq 延迟队列功能
最近在研究rabbitmq,项目中有这样一个场景:在用户要支付订单的时候,如果超过30分钟未支付,会把订单关掉.当然我们可以做一个定时任务,每个一段时间来扫描未支付的订单,如果该订单超过支付时间就关闭 ...
随机推荐
- node基于express的socket.io
前一段事件,我一个同学给他们公司用融云搭建了一套web及时通信系统,然后之前我的公司也用过环云来实现web及时通信,本人对web及时通信还是非常感兴趣的.私下读了融云和环信的开发文档,然后发现如果注册 ...
- Android 自定义 spinner (背景、字体颜色)
转自:http://blog.sina.com.cn/s/blog_3e333c4a010151cj.html 1.准备两张图片,并做好9.png 2.在drawable中定义spinner_se ...
- Zabbix二次开发_02获取数据
最近准备写一个zabbix二次页面的呈现.打算调用zabbix api接口来进行展示. 具体流程以及获取的数据. 1. 获得认证密钥 2. 获取zabbix所有的主机组 3. 获取单 ...
- ubuntu中为Pycharm添加快捷启动方式
1. sudo gedit /usr/share/applications/Pycharm.desktop 2.在文件中添加: [Desktop Entry] Type=Application Nam ...
- 杂项:CDN
ylbtech-杂项:CDN CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快 ...
- ubuntu 查看系统是32位还是64位
查看cpu信息 cat /proc/cpiinfo 查看ubuntu版本: cat /etc/issue 查看系统是32位还是64位 方法1: #查看long的位数,返回32或64 getconf L ...
- git clone的时候filename too long解决办法
在git bash中,运行下列命令: git config --global core.longpaths true
- IO模式调查利器blkiomon介绍
本文链接地址: IO模式调查利器blkiomon介绍 blkiomon 是blktrace工具包带的一个方便用户了解IO情况的工具, 由于blktrace太专业,需要了解的IO协议栈的东西太多,blk ...
- web安全深度剖析 pdf
扫加公众号,回复“web安全深度剖析",免费获取此书.
- jquery knob旋钮插件
<!DOCTYPE html> <html> <head> <title>jQuery Knob 尝试</title> <script ...