ActiveMQ教程(6)— JMS规范中的几个基本概念

由于ActiveMQ是JMS规范的完整实现,所以为了讲清楚ActiveMQ是如何进行存储和调度的,就需要首先说明JMS中和存储、调度有关的几个概念。它们是:

  • 消息收发模式(订阅-发布和负载均衡模式);
  • 消息存储模式(持久化消息和非持久化消息);
  • 订阅模型(持续订阅和非持续订阅)。

订阅发布模式和负载均衡模式


在上篇文章中我们已经详细讲解过订阅-发布模式和负载均衡模式。在ActiveMQ的官方文档中的描述,他们的英文名称分别是TopicsQueue。这两种消息“发送-接受”模式,都是JMS规范中的标准模式。

订阅-发布模式

这里写图片描述
在“订阅-发布”模式下,消息会被复制多份,分别发送给所有“订阅”者。实际上在后文的描述中您将看到,这个复制的过程实际上没有您想象的简单。

负载均衡模式

这里写图片描述
在“负载均衡”模式下,一条消息将会发送给一个消息消费者,如果当前Queue没有消息消费者,消息将进行存储。同样通过后文的介绍,您会发现这其中的过程也并不简单。

持久化消息和非持久化消息


JMS中对非持久化消息和非持久化消息的称呼分别是:NON_PERSISTENT MessagePERSISTENT Meaage。它们指的是消息在任何一种“发送-接受”模式下(“订阅-发布”模式和“负载均衡模式”),是否进行持久化存储。

NON_PERSISTENT Message只存储在JMS服务节点的内存区域,不会存储在某种持久化介质上(后面我们要介绍到AcitveMQ可支持的持久化介质有:KahaBD、AMQ和关系型数据)。在极限情况下,JMS服务节点的内存区域不够使用了,也只会采用某种辅助方案进行转存(例如ActiveMQ会使用磁盘上的一个“临时存储区域”进行暂存)。一旦JMS服务节点宕机了,这些NON_PERSISTENT Message就会丢失。

JMS中对PERSISTENT Meaage的定义是:这些消息不受JMS服务端异常状态的影响,JMS服务端会使用某种持久化存储方案保存这些消息,直到JMS服务端认为这些PERSISTENT Meaage被消费端成功处理。例如ActiveMQ中可以选择的持久化存储方案就包括:KahaDB、AMQ和关系型数据库。

在JMS标准API中,使用setDeliveryMode标记消息发送者是发送的PERSISTENT Meaage还是NON_PERSISTENT Message。示例如下:

......
for(int index = 0 ; index < 10 ; index++) {
    TextMessage outMessage = session.createTextMessage();
    outMessage.setText("这是发送的消息内容:" + index);
    if(index % 2 == 0) {
        sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    } else {
        sender.setDeliveryMode(DeliveryMode.PERSISTENT);
    }
    sender.send(outMessage);
}
......

那么当JMS服务节点重启后(注意不是producer重启),以上代码中发送的10条消息只有其中5条消息能够保存下来。

持续订阅和非持续订阅


持续订阅和非持续订阅,是针对“订阅-发布”模式的细分处理策略,在JMS规范中的标准称呼是:Durable-SubscribersNon-Durable Subscribers

Durable-Subscribers是指在“订阅-发布”模式下,即使标记为Durable-Subscribers的订阅者下线了(可能是因为订阅者宕机,也可能是因为这个订阅者故意下线),“订阅-发布”模式的Topic队列也要保存这些消息(视消息不同的持久化策略影响,保存机制不一样),直到下次这个被标记为Durable-Subscribers的订阅者重新上线,并正确处理这条消息为止。换句话说,标记为Durable-Subscribers的订阅者是否能获得某条消息,和它是否曾经下线没有任何关系。

Non-Durable Subscribers是指在“订阅-发布”模式下,“订阅-发布”模式的Topic队列不用为这些已经下线的订阅者保留消息。当后者将消息按照既定的广播规则发送给当前在线的订阅者后,消息就可以被标记为“处理完成”。

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页