ActiveMQ详解(3)——JMS消息的高级特性

ActiveMQ详解(3)——JMS消息的高级特性

一. 消息的签收(确认)

  1. JMS消息只有被确认后,才认为已经被成功地消费了。消息的成功消费通常包括三个阶段:客户端接收消息、消费者处理消息,和消息被确认。
  2. 在事务性会话中,当一个事务被提交的时候,消息签收自动执行。在非事务性会话中,消息何时被签收取决于创建会话时指定的消息签收模式。消息有一下三种签收模式:
    1. Session.AUTO_ACKNOWLEDGE:当消费者成功从receive()方法返回时,或从MessageListener.onMessage()方法成功返回时,会话自动签收客户端接收的消息。
    2. Session.CLIENT_ACKNOWLEDGE:消费者通过调用消息的acknowledge()方法签收消息。需要注意的是,在这种模式中,消息签收是在会话层上进行的,签收一个被消费的消息,所有已被会话消费的消息都会自动签收。例如,如果一个消费者消费了10条消息,并且签收了其中的第5条,那么所有10条消息都会被确认。
    3. Session.DUPS_OK_ACKNOWLEDGE:允许消息的延迟签收,消费者可以在处理多条消息后一次性签收。这种方式可以降低频繁签收消息所带来的性能损耗,但是如果JMS Provider宕机,可能会产生重复消息。对于重复消息,JMS Provider会将消息头的JMSRedelivered字段置为true。

二. 消息的持久化

  1. JMS支持两种消息提交模式:

    1. PERSISTENT:持久消息,JMS Provider会将该类型的消息持久化,以保证消息不会因为Provider的故障而丢失。
    2. NON_PERSISTENT:非持久化消息。
  2. 持久订阅

    要实现持久订阅,生产者必须创建PERSISTENT的消息,然后消费者可以通过createDurableSubscriber()方法创建持久订阅。

    JMS Provider会存储发布到Topic上的持久订阅的消息,如果最初创建持久订阅的消费者或者其他任何消费者,使用相同的ConnectionFactory和相同的客户端id,相同的主题和订阅名称,再次调用会话的createDurableSubscriber()方法,该持久订阅就会被激活。Provider会将Consumer处于未激活状态时的消息发送给Consumer。

    持久订阅在同一时刻只能有一个激活状态的消费者。持久订阅在创建之后会一直保留,直到调用会话的unsubscribe()方法。

  3. 本地事务

    JMS客户端可以使用本地事务来组合消息的生产和消费。JMS Session接口提供了commit()和rollback()方法。事务提交意味着生产的所有消息都被发送,消费的所有消息都被签收;事务回滚意味着生产的所有消息都被销毁,消费的所有消息被恢复并且重新提交,除非他们已经过期。

三. P2P模型

  1. P2P模型是基于队列的,生产者将消息发送到队列,消费者从队列中接收消息,队列的存在使得消息的异步传输成为可能。队列中可以包含各种消息,JMS Provider提供了管理工具来管理队列的创建和删除。
  2. P2P模型的特点:
    1. 如果在Session关闭时,有一些消息已经被消费者接收,但是还没有确认签收,那么消费者下次连接到相同队列时,这些消息还会被再次接收。
    2. 如果receive()方法设置了筛选条件,那么不满足条件的消息仍会留在队列中,不会被消费。
    3. 队列可以永久地保存消息,直到消息被消费。消费者不用因为担心消息丢失而时刻处于激活状态,这充分体现了异步通信的优势。

四. Pub/Sub模型

  1. Pub/Sub模型定义了如何向一个节点发布和订阅消息,这个节点成为主题——Topic。

    主题可以被认为是消息的传输中介,生产者将消息发布到主题中,消费者从主题中订阅并获取消息。主题使得消息的发送者和订阅者可以保持相互独立,不需要接触就可正常进行消息的传送。

  2. Pub/Sub模型的特点:

    1. 分为持久订阅和非持久订阅。非持久订阅时,消费者无法接收到离线状态时发送过来的消息。在持久订阅时,消费者会向Provider注册一个识别自己身份的ID,当这个消费者处于离线时,Provider会保存所有发往该ID的主题的消息,当消费者再次连接到Provider时,会根据自己的ID得到所有当自己处于离线状态时发送到主题的消息。
    2. 如果在receive()方法中设置了筛选条件,那么不满足条件的客户端不会被接收。
    3. 非持久订阅状态下,不能恢复或者重新创建一个未签收的消息,只有持久订阅才可以。
    4. 如果需要保证所有订阅的消息都被接收,则需要使用持久订阅。如果可以容忍消息的丢失,则可以使用非持久订阅。
    5. 非持久订阅效率高于持久订阅。

猜你喜欢

转载自blog.csdn.net/weixin_34452850/article/details/82319280