ActiveMQ如何接收离线消息

【消息持久化】

ActiveMQ持久订阅设置

通过为发布者设置 PERSISTENT传送模式,为订阅者时使用持久订阅,这样可以保证 Pub/Sub 程序接收所有发布的消息。

消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscription),非持久订阅只有当客户端处于激活状态,也就是和 ActiveMQ 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向ActiveMQ 注册一个识别自己身份的 ID,当这个客户端处于离线时,ActiveMQ会为这个 ID 保存所有发送到主题的消息,当客户端再次连接到ActiveMQ 时, 会根据自己的 ID 得到所有当自己处于离线时发送到主题的消息。持久订阅会增加开销,同一时间在持久订阅中只有一个激活的用户。 建立持久订阅的步骤:

1. 为连接设置一个客户 ID;

2. 为订阅的主题指定一个订阅名称;

上述组合必须唯一。

代码实现持久化订阅

(1)使用queue,即队列时,每个消息只有一个消费者,所以,持久化很简单,只要保存到数据库即可

。然后,随便一个消费者取走处理即可。某个消费者关掉一阵子,也无所谓。

(2)使用topic,即订阅时,每个消息可以有多个消费者,就麻烦一些。

首先,假设消费者都是普通的消费者,
------------------------
<1>activemq启动后,发布消息1,可惜,现在没有消费者启动着,也就是没有消费者进行了订阅。那么

,这个消息就被抛弃了。

<2>消费者1启动了,连接了activemq,进行了订阅,在等待消息~~

activemq发布消息2,OK,消费者1收到,并进行处理。消息抛弃。

<3>消费者2也启动了,连接了activemq,进行了订阅,在等待消息~~

activemq发布消息3,OK,消费者1,消费者2都收到,并进行处理。消息抛弃。

<4>消费者1关掉了。

activemq发布消息4,OK,消费者2收到,并进行处理。消息抛弃。

<5>消费者1又启动了。

activemq发布消息5,OK,消费者1,消费者2都收到,并进行处理。消息抛弃。
-----------------------------
总结一下:
activemq只是向当前启动的消费者发送消息。
关掉的消费者,会错过很多消息,并无法再次接收这些消息。

如果发送的消息是重要的用户同步数据,错过了,用户数据就不同步了。

那么,如何让消费者重新启动时,接收到错过的消息呢?

答案是持久订阅。
-----------------------------

普通的订阅,不区分消费者,场地里有几个人头,就扔几个馒头。
持久订阅,就要记录消费者的名字了。
张三说,我是张三,有馒头给我留着,我回来拿。
李四说,我是李四,有馒头给我留着,我回来拿。
activemq就记下张三,李四两个名字。

那么,分馒头时,还是一个人头给一个馒头。
分完了,一看张三没说话,说明他不在,给他留一个。
李四说话了,那就不用留了。

张三回来了,找activemq,一看,这不张三吧,快把他的馒头拿来。
可能是一个馒头,也可能是100个馒头,就看张三离开这阵子,分了多少次馒头了。

activemq区分消费者,是通过clientID和订户名称来区分的。
-----------------------------
// 创建connection
connection = connectionFactory.createConnection();
connection.setClientID("bbb"); //持久订阅需要设置这个。
connection.start();

// 创建session
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

// 创建destination
Topic topic = session.createTopic("userSyncTopic"); //Topic名称

//MessageConsumer consumer = session.createConsumer(topic); //普通订阅
MessageConsumer consumer = session.createDurableSubscriber(topic,"bbb"); //持久订阅

还有一点,消息的生产者,发送消息时用使用持久模式
MessageProducer producer = ...;
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
不设置,默认就是持久的

(5)使用相同的“clientID”,则认为是同一个消费者。两个程序使用相同的“clientID”,则同时只能有一个连接到activemq,第二个连接的会报错。

(6)activemq的设置在conf/activemq.xml中,默认消息是保存在data/kahadb中,重启activemq消息不会丢。

可以访问http://localhost:8161/admin/index.jsp:查看当前的队列、Topic和持久订户的信息、发送消息等等,很方便。

可以复制activemq-jdbc.xml中的内容过来,修改一下,就可以把消息保存在其它数据库中了。

时间: 2024-11-07 06:54:23

ActiveMQ如何接收离线消息的相关文章

openfire接收离线消息

先接收离线消息后再通知openfire上线 //获取离线消息 OfflineMessageManager offlineMessageManager=new OfflineMessageManager(connection); Iterator<Message> messages=offlineMessageManager.getMessages(); while (messages.hasNext()){ Message msg=messages.next(); System.out.pri

离线消息如何实现?-- ESFramework 4.0 快速上手(02)

在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFramework快速开发,也还有很多可以介绍的内容,于是,我想再多写几篇文章来说明现实通信系统中的一些常见需求如何使用ESFramework快速实现.本文是为第一篇,介绍离线消息的原理和实现. 一.如何截获离线消息 阅读了ESFramework 4.0 快速上手朋友都知道,一个在线用户给另一个用户发送文本信

解决Springboot整合ActiveMQ发送和接收topic消息的问题

环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> &l

【转】可在广域网部署运行的QQ高仿版 -- GG叽叽V3.2,增加离线消息、离线文件功能(源码)

(几句题外话:虽然就如何将GG发展为一个有商业价值的产品,我还没有很清晰明确的思路,但是从GG发布以来,通过GG认识了一些朋友,也接了一些小单子,赚了一点小钱.有了一点甜头,目前和2.3个好朋友一起做做小项目也是不错的,这未尝不是一条养家糊口之路了?呵呵) 距离上次更新(GG叽叽V3.0,完善基础功能)正好有1个月了,在这个月中,我主要为GG增加了离线消息和离线文件的功能.之所以将这两个功能提前实现,是因为至GG发布以来,就有很多朋友问我在GG的基础上如何实现离线消息和离线文件.看来作为一个能用

可在广域网部署运行的QQ高仿版 -- GG叽叽V3.2,增加离线消息、离线文件功能(源码)

(几句题外话:虽然就如何将GG发展为一个有商业价值的产品,我还没有很清晰明确的思路,但是从GG发布以来,通过GG认识了一些朋友,也接了一些小单子,赚了一点小钱.有了一点甜头,目前和2.3个好朋友一起做做小项目也是不错的,这未尝不是一条养家糊口之路了?呵呵) 距离上次更新(GG叽叽V3.0,完善基础功能)正好有1个月了,在这个月中,我主要为GG增加了离线消息和离线文件的功能.之所以将这两个功能提前实现,是因为至GG发布以来,就有很多朋友问我在GG的基础上如何实现离线消息和离线文件.看来作为一个能用

XMPP——Smack[5]文件传输及离线消息的获取

三天时间,赶在最后一下午实现了文件的传输,本来需要实现离线文件的发送的,一直没想好怎么弄,找openfire的离线文件插件没找到,后来想出一种方法,起服务器时起了一个系统用户,一直在线,当用户发送离线文件,检测到对方不存在,先发给系统用户,存到服务器路径,并在数据库中保存信息,当对方上线时,系统用户查表,拿文件发送 想是这么想的,问题是时间太紧,没有实现,囧. 下一篇写离线消息和离线文件 文件的发送 开一个文件选择框,选中文件后再调用下面的方法 [java] view plaincopyprin

OpenFire源码学习之二十五:消息回执与离线消息(下)

这一篇紧接着上面继续了. 方案二 基于redis的消息回执.主要流程分为下面几个步骤: 1)将消息暂存储与redis中,设置好消息的过期时间 2)客户端回执消息id来消灭暂存的消息 3)开通单独线程论坛在第1)步中的消息.根据消息的时间重新发送消息.如果消息第一次存放的时间大雨有效期(自定义10秒),解析消息中的to查找用户是否还在线.如果在则T掉(因为它长时间不理会服务的重要命令),如果不在线则将消息放置离线表. OK,先来看看消息的存储格式吧. 1.MESSAGE消息 用户集合 SADD 

如何在App中实现IM功能之二快速实现离线消息模块——箭扣科技Arrownock

如何在App中实现IM功能 之二 快速实现离线消息模块 一个App在实际使用聊天功能的时候,并非是一直呆在一个界面的,在等待好友发消息来的同时,有可能已经跳转到其他界面,也有可能切换到其他App. 在当前的App进入后台.好友发来消息时,需要给设备推送一条消息.以安卓为例,收取离线消息通知需要绑定anPush,具体做法是调用anIM.bindAnPushService(anID, AppKey, anPushType). 在App进入后台时,调用anIM.disconnect():在App回到前

如何在App中实现IM功能之三快速实现离线消息推送模块——箭扣科技Arrownock

如何在App中实现IM功能 之三 快速实现离线消息推送模块 推送是社交功能里最常见的功能之一,许多使用IM++平台的开发者都会用到,本节我们将为大家带来如何使用IM++平台快速实现离线推送. 使用过Arrownock产品的开发者应该知道,如果要实现离线消息推送在Android设备上有4个步骤,iOS设备上有3个步骤. Android的步骤是: l anIM.connect,anPush.register,anPush.enable,anIM.bindAnPushService iOS的步骤是: