一,消息的持久化和非持久化
①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性质,否则不是。
到这里为止,已经知道若ActiveMQ采用持久传输模式,则会把消息持久化到磁盘中。那么,消息是以何种形式存储的呢?是存储到文件中还是存储到数据库中? 存储的数据结构如何实现?是B树还是其他?…… 关于这些问题都是很直接值得研究的。关于消息持久化内容,可简单参考:
③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)