现在的位置: 首页 > 综合 > 正文

Acknowledgement Modes

2014年12月03日 ⁄ 综合 ⁄ 共 12030字 ⁄ 字号 评论关闭

http://blog.csdn.net/geloin/article/details/7967059

注:JMS&MQ系统是我在学习ActiveMQ过程中的一些积累和总结,其中的知识大部分来源于网络和《ActiveMQ in Action》,理论上并不能算是原创,此处予以说明,后文不再赘述。

        JMS定义了两种消息传递域:点对点消息传递域和发布/订阅消息传递域。

        点Q对点消息传递域的特点:
        1. 每个消息只能有一个消费者;
        2. 消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,它都可以提取消息。

        发布/订阅消息传递域的特点:
        1. 每个消息可以有多个消费者;
        2. 生产者和消费者之间有时间上的关联性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许客户创建持久阅读,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息。

        在点对点消息传递域中,目的地为队列(Queue);在发布/订阅消息传递域中,目的地为主题(Topic)。

        消息的消费可以采用以下两种方法之一:
        1. 同步消费。通过调用消费者的receive方法从目的地中显式地提取消息。receive方法可以一直阻塞到消息到达;
        2. 异步消费。客户可以为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。

        JMS消息由以下三部分组成:
        1. 消息头。每个消息头字段都有相应的getter和setter方法;
        2. 消息属性。如果需要除消息头字段以外的值,那么可以使用消息属性;
        3. 消息体。JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage和ObjectMessage。

        JMS消息只有在被确认之后,才认为已经被成功消费。消息的成功消费通常包含三个阶段:客户接收消息、客户处理消息和消息被确认。

        在事务性会话中,当一个事务被提交时,确认自动发生。在非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)。该参数有以下三个可选值:
        1. Session.Auto_ACKNOWLEDGE。当客户成功地从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。
        2. Session.CLIENT_ACKNOWLEDGE。客户通过消息的acknowledge方法确认消息。需要注意的是,在这种模式中,确认是在会话层进行:确认一个被消费的消息将自动确认所有已被会话消费的消息。例如,如果一个消息消费者消费了10个消息,然后确认第5个消息,那个所有10个消息都被确认。
        3. Session.DUPS_ACKNOWLEDGE。在会话迟钝等情况下确认消息。如果JMS provider失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider必须把消息头的JMSRecelivered字段设置为true。

        JMS支持以下两种消息提交模式:
        1. PERSISTENT。指示JMS provider持久保存消息,以保证消息不会因为JMS provider的失败而丢失。
        2. NON_PERSISTENT。不要求JMS provider持久保存消息。

 

====================

http://blog.csdn.net/woohooli/article/details/6589301

 

JMS Details

This section provides a more detailed description of JMS. In particular, we explore the acknowledgement modes, which are fundamental to understanding the reliability aspects of a JMS provider. Also, this section covers message producers and consumers, as
well as the details of exception listeners and message selectors.

As described previously, the Pub/Sub and P2P models have a lot in common, and unless otherwise noted, the information described in this section applies to both models. The only major differences between the two models in terms of the JMS API's is that the
P2P model supports a queue browser and the Pub/Sub models support durable subscribers.

Acknowledgement Modes

Message acknowledgement is purely a consumer side concept, which relates to how a consumer tells the JMS provider that is has received a messages. On the producer side, the only notion of acknowledgement consists of a successful invocation of either the
topic publisher's publish method or the queue sender's send method.

Acknowledgment of a message means that the JMS provider must never deliver the message to the consumer in question again. This also means that the JMS provider can release any resources it is occupying on behalf of said message. To minimize resource consumption,
consumer applications should therefore acknowledge messages as quickly as possible.

JMS support a number of message acknowledgement modes:

Duplicates Allowed

Consumer applications specify this acknowledge mode using the DUPS_OK_ACKNOWLEDGE constant defined in the Session interface. Using this mode, the session acknowledges message lazily, which provides faster message processing, with the penalty
that some duplicate messages may be delivered multiple times if JMS fails. Only applications that are tolerant to message duplicates should use this acknowledge mode.

Auto acknowledge

This is the default acknowledge mode, which is specified using the AUTO_ACKNOWLEDGE constant defined in the Session interface. For each message, the session automatically acknowledges that a client has received a message either:

  • Just before the call to a message consumer's receive or receiveNoWait return a message.

  • Right after the onMessage method returns successfully after invoking the consumer's MessageListener

If a JMS provider or the message consumer crashes while it is processing a message, this message is subject to either re-delivery or loss when using the automatic acknowledgement mode.

With synchronous receive, the message will be lost of JMS acknowledges it but crashes before receive returns the message to the consumer. With an asynchronous message listener, a duplicate will happen if JMS crashes after
onMessage completed but before the acknowledgement was recorded.

Note that these situations are not limitations of a JMS implementation but the nature of doing automatic acknowledgements in a distributed system. The only way to prevent this is by maintaining persistent state in the client, or by using a distributed transaction.

Client acknowledge

Consumer applications specify this acknowledge mode using the CLIENT_ACKNOWLEDGE constant defined in the
Session interface. This acknowledgement mode gives consumer more control over when messages are acknowledged. A consumer can group a number of messages and then invoke the
acknowledge method of the Message to instruct the JMS provider that the message (and all other messages received up until this point) have been consumed.

When a consumer uses client acknowledge, it can use the recover method of the session to revert back to its last check point. This causes the session to re-deliver all messages that have not yet been acknowledged by the consumer. Note that if
a client crashes and later re-connects to its queue or topic, the session will effectively be recovered and the consumer will receive all un-acknowledged messages.

Transactional Acknowledge

The session finally supports a different kinds of acknowledgement mode, which is referred to as a transacted session. A transacted session is a related group of consumed and produced messages that are treated as a single work unit. A transaction can be either
committed or rolled back.

When the session's commit method is called, the consumed messages are acknowledged, and the associated produced messages are sent. When a session's
rollback method is called, the produced messages are destroyed, and the consumed messages are recovered.

A transacted session always has a "current" transaction and applications do not explicitly start one. As soon as either the
commit or rollback method is called, the current transaction ends and a new transaction is immediately started. These method can only be called on a transacted session.

The graph below illustrates a transacted session as using a "bucket" for holding on to messages and acknowledgements. The MSG's and ACK's are flushed when the
commit orrollback method is called.

A typical use of transacted sessions is to consume and produce a message atomically. If an application moves messages from one destination to another, it should use a transacted session to ensure that the message is either successfully transferred, or not
transferred at all. In this case, the commit method should be called after each message.

Message Producers

Message producers send or publish messages to a destination. The QueueSender and
TopicPublisher interfaces support several variations of either a send or
publish method for sending messages.

The producer application creates the message and is required to set the various properties of the message. If these properties are not specified in the
send or publish method, JMS will assign what has been set as the default value for the queue sender or topic publisher:

  • The destination of the message. In P2P this is a queue and in Pub/Sub it's a topic.

  • The message delivery mode. JMS support persistent and non-persistent message delivery modes, with persistent being the default.

  • The message priority. JMS guarantees FIFO order for messages of the same priority but will attempt to expedite messages of higher priority.

  • The expiry of the message. This is also referred to a time-to-live (TTL) for the message. Expired messages are not delivered to consumers.

Once the invocation of the send or publish method returns successfully, JMS has received the message. For persistent messages this means that the message has successfully been written into some persistent store and is guaranteed
not to be lost until the recipient has acknowledged it.

Message Consumers

A message consumer receives messages from a destination. The QueueReceiver and
TopicSubscriber interfaces both extends the MessageConsumer, which support two way of receiving messages:

Synchronously

The client calls one of the receive methods defined in the MessageConsumer interface:

  • receive - This method can be called with out without a timeout. The consumer block either indefinitely or for the specified amount of time to retrieve a message. If a message was not available on the destination before the timeout expired, null
    is returned.

  • receiveNoWait - This method checks for a message and returns immediately with either null or a message if one is available on the destination to which to consumer is registered.

Note that before a consumer application can start to receive messages, it must call the
start method on the
Connection
object. The start method is a signal to the JMS provider to start the flow on messages to all sessions created by the connection in question.

Asynchronously

The client registers a MessageListener with the MessageConsumer using its
setMessageListener method. Note that the asynchronous and synchronous models can not be mixed and it is not allowed to call the receive methods on a consumer with a message listener.

A message listener is simply an object, which implements the onMessage method. This method has a single argument, which is a JMS message. A message listener is not allowed to raise any exceptions and a consumer application should always try
to catch any exceptions and deal with them.

Ordinarily, the JMS provider will resolve connection problems. If an error occurs, the provider normally raises an exception when an application tries to send or receive a message. However, when using a message listener this is not possible because the consumer
waits for the provider to invoke it.

Therefore, JMS support an interface called an ExceptionListener which is used to communicate exceptions to clients. The exception listener is primarily available to support asynchronous communication, but is is in general recommended that client application
use it.

The exception listener is set using the setExceptionListener method on the

Connection
object. As opposed to a regular message listener, the exception listener is set once per connection instead of once per consumer. By default a connection does not have an exception listener.

So far, the discussion has covered both the P2P and Pub/Sub messaging models. However, both P2P and Pub/Sub support special kinds of message receivers. The P2P model support a queue browser and Pub/Sub support a durable subscriber.

Queue Browser

A queue browser is a special consumer that can retrieve but not consume messages. A queue browser supports the

QueueBrowser
interface, which has methods for looking at queue messages without actually removing them from the queue.

The QueueBrowser interface provides a familiar
Enumeration
which elements are messages. The order of messages in the enumeration corresponds to the order in which a regular queue receiver would receive them (subject to message expiry and arrival of new, high-priority messages).

Durable Subscriber

A durable subscriber is used to receive persistent topic messages. Since regular, transient topic subscribers do not survive crashes of either the JMS provider or the subscriber itself, the JMS provider will typically not persist topic messages when the
topic only has transient subscribers.

The above is a consequence of the fact that a topic does not retain messages when there are no subscribers. In Pub/Sub messaging, subscribers will only get messages that were received by the topic after the subscription was made. Therefore, there can be
no concept of persistent messages if connections can not survive a crash.

A durable subscriber can survive crashes, and the subscription is not lost until it is explicitly un-subscribed. If a durable subscriber is temporarily unavailable, the JMS provider will buffer messages on it behalf. When the subscriber comes back and re-connects,
it will receive all buffered messages.

Durable subscribers require a connection client identifier. This identifier is part of the subscription name and must be set using the
setClientID method on the
Connection
. As with an exception listener, this is set once per connection and the client identifier will apply to all durable subscribers within said connection.

Message Selectors

A message selector is an object invoked by the JMS provider to restrict messages from being delivered unless they meet certain specified criteria. Message selectors examine the message header fields and properties and then compare them to a context string
that has been specified by the consumer.

The context string used by the message selector is built from syntax based on a subset of SQL92 conditional expression syntax. If you are familiar with JDBC, you essentially query as if the message properties where column names. The following table describes
some common values. For a complete list, please refer to the JMS specification.

Value Examples
Comparison operators Amount <= 5
Month = 'January'
Logical operators JMSPriority > 3 AND Value = 42
Width = 2 OR Height > 3
Level < 4 AND NOT Error
Arithmetic operators Amount * 22.3 + Tax / 1.45 < 4220.12
-Value * 9 < 12
SQL operators Amount BETWEEN 12 AND 22
Quote IN ('SSSW','CSCO','MSFT')
Property IS NULL
Number LIKE '12%3'
Word LIKE 'hel_o'

Un-selected message in the P2P model are retained on the queue so that if one consumer does not select a message, the JMS provider will attempt to re-assign it to another consumer (or keep it on the queue for some future consumer).

In the Pub/Sub model, un-selected message are discarded and from a subscriber's point of view, it will be as if the messages was never sent to the topic. The message may be selected by other subscribers of the topic.

 

抱歉!评论已关闭.