RabbitMq(7)消息延时推送
应用场景
目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如:
- 淘宝七天自动确认收货。在我们签收商品后,物流系统会在七天后延时发送一个消息给支付系统,通知支付系统将款打给商家,这个过程持续七天,就是使用了消息中间件的延迟推送功能。
- 12306 购票支付确认页面。我们在选好票点击确定跳转的页面中往往都会有倒计时,代表着 30 分钟内订单不确认的话将会自动取消订单。其实在下订单那一刻开始购票业务系统就会发送一个延时消息给订单系统,延时30分钟,告诉订单系统订单未完成,如果我们在30分钟内完成了订单,则可以通过逻辑代码判断来忽略掉收到的消息。
在上面两种场景中,如果我们使用下面两种传统解决方案无疑大大降低了系统的整体性能和吞吐量:
- 使用 redis 给订单设置过期时间,最后通过判断 redis 中是否还有该订单来决定订单是否已经完成。这种解决方案相较于消息的延迟推送性能较低,因为我们知道 redis 都是存储于内存中,我们遇到恶意下单或者刷单的将会给内存带来巨大压力。
- 使用传统的数据库轮询来判断数据库表中订单的状态,这无疑增加了IO次数,性能极低。
- 使用 jvm 原生的 DelayQueue ,也是大量占用内存,而且没有持久化策略,系统宕机或者重启都会丢失订单信息。
消息延时推送实现
在 RabbitMQ 3.6.x 之前我们一般采用死信队列+TTL过期时间来实现延迟队列。
在 RabbitMQ 3.6.x 开始,RabbitMQ 官方提供了延迟队列的插件,可以下载放置到 RabbitMQ 根目录下的 plugins 下
资源地址:https://www.rabbitmq.com/community-plugins.html
我这边是在windows下,下载解压放如plugin,然后cmd:
D:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.9\sbin>rabbitmq-plugins enable rabbitmq_delayed_message_exchange
代码样例
/**
* 延时Queue
*/
public static final String DELAY_QUEUE = "delay.queue"; @Bean
public Queue delayQueue(){
return new Queue(DELAY_QUEUE, true);
} @Bean
TopicExchange delayExchange() {
Map<String, Object> pros = new HashMap<String, Object>();
//设置交换机支持延迟消息推送
pros.put("x-delayed-message", "topic");
TopicExchange delayTopicExchange = new TopicExchange("delayTopicExchange",true,false,pros); delayTopicExchange.setDelayed(true);
return delayTopicExchange;
} @Bean
Binding bindingDelayExchange(Queue delayQueue, TopicExchange delayExchange) {
return BindingBuilder.bind(delayQueue).to(delayExchange).with("delay.#");
}
生产者:
public void delaySend() throws IOException {
User user = new User();
user.setUserName("Sender1.....");
user.setMobile("6666666");
byte[] body = Base64Utils.obj2byte(user);
Message message = new Message(body,new MessageProperties());
//延时插件https://www.rabbitmq.com/community-plugins.html
//然后放plugin包
//启用插件:rabbitmq-plugins enable rabbitmq_delayed_message_exchange
//Lambda表达式
MessagePostProcessor messagePostProcessor = message1 -> {
//设置消息持久化
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
message.getMessageProperties().setHeader("x-delay", 10000);
//message.getMessageProperties().setDelay(20000);
return message;
};
System.out.println("发送演示消息>>>>>"+new Date());
rabbitTemplate.convertAndSend("delayTopicExchange","delay.message",message,messagePostProcessor);
}
rabbitTemplate 通常在SpringBoot 中默认配置
测试用例:
@Test
public void send6() throws Exception {
topicSender.delaySend();
}
运行下:

消费端(另一工程):
/**
* 延时Queue
*/
public static final String DELAY_QUEUE = "delay.queue";
package com.example.demo.rabbitMq.exchange.topic; import com.example.demo.utils.Base64Utils;
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.stereotype.Component; import java.io.IOException;
import java.util.Date; @Component
public class TopicReceiver6 { private Logger logger = LoggerFactory.getLogger(this.getClass()); @RabbitListener(queues = TopicRabbitConstant.DELAY_QUEUE)
public void process(Message message, Channel channel) throws IOException {
try {
System.out.println("Receiver6 : " + new Date() + ">>>>" + Base64Utils.byteToObj(message.getBody())); } catch (Exception e) {
logger.error("接收失败",e);
}
}
}
整体测试验证
1、启动消费端
2、生产者发送消息
结果:
生产者工程Console:

消费这边工程Console:

时间间隔10s
参考:
https://www.cnblogs.com/haixiang/p/10966985.html
RabbitMq(7)消息延时推送的更多相关文章
- RabbitMQ 延迟队列,消息延迟推送
目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制
2013年10月06日最新整理. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制 微信公共平台消息主动推送接口一直是腾讯的私用接口,相信很多朋友都非常想要用到这个功能. 通过学习 ...
- Swift - 本地消息的推送通知(附样例)
使用UILocalNotification可以很方便的实现消息的推送功能.我们可以设置这个消息的推送时间,推送内容等. 当推送时间一到,不管用户在桌面还是其他应用中,屏幕上方会都显示出推送消息. 1, ...
- .NET之微信消息模板推送
最近在项目中使用到了微信消息模板推送的功能,也就是将对应的消息推送到对应的用户微信上去,前提是你必须要有一个微信公众号并且是付费了的才会有这个功能,还有就是要推送的用户必须是的关注了你的微信公众号的. ...
- dwr3实现消息精确推送详细步骤
最近项目中需要用到推送消息,找了很久终于找到一篇不错的文章,方便以后查看就转载了,也分享给大家,希望能帮到有需要的人. 第一.在项目中引入dwr.jar,然后在web.xml中进行配置,配置如下: & ...
- 基于HTTP协议之WEB消息实时推送技术原理及实现
很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...
- NET SignaiR 实现消息的推送,并使用Push.js实现通知
一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...
- spring boot 集成 websocket 实现消息主动推送
spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...
随机推荐
- web 前端3 javascript基础
JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理. 一.如何编写 1.J ...
- Vue 基础 day06 webpack 3.x 结合vue
在普通页面使用 render 函数渲染组件 var login = { template: '<h3>login</h3>' } var vm = new Vue({ // c ...
- windows10配置Docker容器独立IP地址互相通信
Docker官方推荐我们通过端口映射的方式把Docker容器的服务提供给宿主机或者局域网其他容器使用.一般过程是: 1.Docker进程通过监听宿主机的某个端口,将该端口的数据包发送给Docker容器 ...
- RD Client、TeamViewer连接主机
一.使用RD Client连接远程桌面 1.设置本地主机 2.查看电脑ip 3.手机安装RD Client 应用商店下载 Microsoft Remote Desktop PC name填入查询到的I ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- 小白学Python(16)——pyecharts 绘制地理图表 Geo
Geo-基本示例 from example.commons import Faker from pyecharts import options as opts from pyecharts.char ...
- python pickle模块的用法
pickle用于python特有的类型,和python的数据类型间进行转换,提供四个功能 dumps,dump,loads,load. pickle 的用法 #pickle.dumps 将数据通过特殊 ...
- 利用反射优化Servlet抽象出父类BaseServlet
在编写servlet的时候发现每个servlet里面的doPost方法都如: protected void doPost(HttpServletRequest request, HttpServlet ...
- SSH简单Demo
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="3 ...
- websocket无法注入bean问题解决方案
websocket服务端往往需要和服务层打交道,因此需要将服务层的一些bean注入到websocket实现类中使用,但是呢,websocket实现类虽然顶部加上了@Component注解,依然无法通过 ...
