JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系

一,消息的持久化和非持久化

①DeliveryMode

这是传输模式。ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent delivery),默认情况下使用的是持久传输。

可以通过MessageProducer 类的 setDeliveryMode方法设置传输模式

MessageProducer producer = ...;
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

持久传输和非持久传输最大的区别是:采用持久传输时,传输的消息会保存到磁盘中(messages are persisted to disk/database),即“存储转发”方式。先把消息存储到磁盘中,然后再将消息“转发”给订阅者。

采用非持久传输时,发送的消息存储到磁盘中。

采用持久传输时,当Borker宕机 恢复后,消息还在。采用非持久传输,Borker宕机重启后,消息丢失。比如,当生产者将消息投递给Broker后,Broker将该消息存储到磁盘中,在Broker将消息发送给Subscriber之前,Broker宕机了,如果采用持久传输,Broker重启后,从磁盘中读出消息再传递给Subscriber;如果采用非持久传输,这条消息就丢失了。

关于传输模式的官方文档,可参考

关于Message Durability 和 Message Persistence的区别:我是在《ActiveMQ in Action》中看到的,理解如下:

②Message Persistence

Message persistence is independent of the message domain.
It is used to indicate the JMS application‘s ability to handle missing messages in the event of a JMS provider failure. 

这说明:1)Message Persistence 与Domain无关。 2)Message persistence 与传输模式有关,如果某消息 使用的是持久传输,则该消息具有 Persistence性质,否则不是。

③Durability of messages(Message Durability)

Message durability can only be achieved with the pub/sub domain.
When clients connect to a topic, they can do so using a durable or a non-durable subscription.

以上说明了两点:1)Durability of messages 只针对发布订阅模型(Domain)。 2)持久订阅和非持久订阅是针对Topic而言的,不是针对Queue的。

也就是说,如果某个消息被持久订阅者订阅了,那么该消息就具有:Durability,否则就是NonDurability

二,持久订阅者和非持久订阅者

Durable Subscribers and NonDurable Subscribers

首先,持久订阅者和非持久订阅者针对的Domain是Pub/Sub,而不是P2P

当Broker发送消息给订阅者时,如果订阅者处于 inactive 状态持久订阅者可以收到消息,而非持久订阅者则收不到消息。

类似于QQ消息,别人给你发了离线消息,如果是非持久订阅者 就收到不离线消息。

造成的影响是:当持久订阅者处于 inactive 状态时,Broker需要为持久订阅者保存消息,如果持久订阅者订阅的消息太多则会溢出。(当消息投递成功之后,Broker就可以把消息删除了)

一个具体的官方实例如下:

For example imagine a durable subscriber S starts up subscribing to topic T at time D1.
Some publisher sends messages M1, M2, M3 to the topic and S will receive each of these messages.
Then S is stopped and the publisher continues to send M4, M5.
When S restarts at D2, the publisher sends M6 and M7.
Now S will receive M4, M5 followed by M6 and M7 and all future messages. i.e. S will receive all messages from M1..M7.

This is the difference between durable and non-durable consuming.
 If S were a non-durable consumer then it would only have received M1, M2, M3 and M6, M7 - not M4 and M5.
 i.e. because the subscription is durable, S will receive every message sent to T whether the subscriber is running or not.
 For non-durable topics, only messages delivered to the topic T when S is running are delivered.

Durable Queues(Topics) and NonDurable Queues(Topics)

区别:参考链接

三,参考资料

http://blog.christianposta.com/guaranteed-messaging-for-topics-the-jms-spec-and-activemq/

理解JMS规范中消息的传输模式和消息持久化

理解JMS规范中的持久订阅和非持久订阅

时间: 2024-08-02 11:01:25

JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系的相关文章

JMS学习五(ActiveMQ的本地事务)

1.ActiveMQ的本地事务 在一个JMS客户端,可以使用本地事务来组合消息的发送和接收.JMS Session接口提供了commit和rollback方法.事务提交意味着生产的所有消息被发送,消费的所有消息被确认:事务回滚意味着生产的所有消息被销毁,消费的所有消息被恢复并重新提交,除非它们已经过期. 事务性的会话总是牵涉到事务处理中,commit或rollback方法一旦被调用,一个事务就结束了,而另一个事务被开始.关闭事务性会话将回滚其中的事务. 需要注意的是,如果使用请求/回复机制,即发

JMS学习(六)-ActiveMQ的高可用性实现

一,ActiveMQ高可用性的架构 ActiveMQ的高可用性架构是基于Master/Slave 模型的.ActiveMQ总共提供了四种配置方案来配置HA,其中Shared Nothing Master/Slave 在5.8版本之后不再使用了,并在ActiveMQ5.9版本中引入了基于Zookeeper的Replicated LevelDB Store HA方案. 二,Master/Slave架构的配置解释 ①Shared Nothing Master/Slave   该架构最大的特点是: 1)

JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储

一,介绍 自ActiveMQ5.4以来,KahaDB成为了ActiveMQ默认的持久化存储方式.相比于原来的AMQ存储方式,官方宣称KahaDB使用了更少的文件描述符,并且提供了更快的存储恢复机制. 二,KahaDB存储配置 在 conf/activemq.xml 中配置如下: <broker brokerName="broker" ... > <persistenceAdapter> <kahaDB directory="activemq-da

JMS学习(八)-ActiveMQ Consumer 使用 push 还是 pull 获取消息

ActiveMQ是一个消息中间件,对于消费者而言有两种方式从消息中间件获取消息: ①Push方式:由消息中间件主动地将消息推送给消费者:②Pull方式:由消费者主动向消息中间件拉取消息.看一段官网对Push方式的解释: To be able to achieve high performance it is important to stream messages to consumers as fast as possible so that the consumer always has a

Scala学习(五)---Scala中的类

Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. 类中的字段自动带有getter方法和setter方法 2. 你可以用定制的getter/setter方法替换掉字段的定义,而不必修改使用类的客户端,这就是所谓的"统一访问原则" 3. 用@BeanProperty注解来生成JavaBeans的getXxx/setXxx()方法 4. 每个类

JS学习五(js中的事件)

[JS中的事件分类] 1.鼠标事件 click/bdlclick/onmouseover/onmouseout 2. HTML事件 onload/onscroll/onsubmit/onchange/onfocus 3. 键盘事件 keydown:键盘按下时触发 keypress:键盘按下并松开时的瞬间触发 keyup:键盘抬起时触发 [注意事项] ①执行顺序:keydown-->keypress-->keyup ②当长按时,会循环执行keydown-->keypress ③有keydo

个人学习C++过程中对const的总结:初始化系列之用字面值常量与其他类型的值初始化的区别(一)

const这个系列博大精深,在学习过程一点一点积累记录.但是由于随笔在发布之后不能修改,有了新的想法之后不能再在原随笔上修改,只好用一个个系列来慢慢积累. 哈哈,在发布之后发现是可以继续编辑的,好吧,不管了,这种方式挺好. 正文: 昨晚接触到一个算法题目,回文字符串,在网上找了某段代码,但是发现有点问题,原形大概如下: .... const int len=mystr.size(); //mystr是string的一个实例,其实我挺奇怪这里为什么用int而不是string::size_type或

ActiveMQ中消息的重发与持久化保存

消息中间件解决方案续 上一篇中我们讲到了在Spring工程中基本的使用消息中间件,这里就不在继续赘述. 针对消息中间件,这篇讲解两个我们常遇到的问题. 问题1:如果我们的消息的接收过程中发生异常,怎么解决? 问题2:发布订阅模式(Topic)下如果消费端宕机引起的消息的丢失,怎么解决? 问题解决方案: 问题1暂时有两种解决方案:第一种是开启消息确认机制,第二种开启事务.下面会在点对点模式下进行演示. 问题2的解决方案:实现发布订阅消息的持久化保存. 根据上面的解决方案搭建工程如下:测试消息的重发

spring+activemq中多个consumer同时处理消息时遇到的性能问题

最近在做数据对接的工作,用到了activemq,我需要从activemq中接收消息并处理,但是我处理数据的步骤稍微复杂,渐渐的消息队列中堆的数据越来越多,就想到了我这边多开几个线程来处理消息. 可是会发现,服务器占用的网络带宽变的异常的高,仔细分析发现,mq入队时并没有异常高的网络流量,仅仅在出队时会产生很高的网络流量.最终发现是spring的jmsTemplate与activemq的prefetch机制配合导致的问题.研究源码发现jmsTemplate实现机制是:每次调用receive()时都