实践ActiveMQ

确认模式

JMS原生支持的确认模式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    /** With this acknowledgment mode, the session automatically acknowledges
      * a client's receipt of a message either when the session has successfully
      * returned from a call to <CODE>receive</CODE> or when the message
      * listener the session has called to process the message successfully
      * returns.
      */
    // 只有当receive方法或onMessage方法成功执行后才反馈确认,当宕机时,可能会出现重复消费
    static final int AUTO_ACKNOWLEDGE = 1;

    /** With this acknowledgment mode, the client acknowledges a consumed
      * message by calling the message's <CODE>acknowledge</CODE> method.
      * Acknowledging a consumed message acknowledges all messages that the
      * session has consumed.
      *
      * <P>When client acknowledgment mode is used, a client may build up a
      * large number of unacknowledged messages while attempting to process
      * them. A JMS provider should provide administrators with a way to
      * limit client overrun so that clients are not driven to resource
      * exhaustion and ensuing failure when some resource they are using
      * is temporarily blocked.
      *
      * @see javax.jms.Message#acknowledge()
      */

    static final int CLIENT_ACKNOWLEDGE = 2;

    /** This acknowledgment mode instructs the session to lazily acknowledge
      * the delivery of messages. This is likely to result in the delivery of
      * some duplicate messages if the JMS provider fails, so it should only be
      * used by consumers that can tolerate duplicate messages. Use of this 
      * mode can reduce session overhead by minimizing the work the
      * session does to prevent duplicates.
      */

    static final int DUPS_OK_ACKNOWLEDGE = 3;

Spring封装的AbstractMessageListenerContainer对消息确认模式的定义如下:

1
2
3
4
5
6
The listener container offers the following message acknowledgment options:
    // 调用onMessage之前确认,即使宕机,也不会出现重复消费
    "sessionAcknowledgeMode" set to "AUTO_ACKNOWLEDGE"(1) (default): Automatic message acknowledgment before listener execution; no redelivery in case of exception thrown.
    // 类似JMS原生的AUTO_ACKNOWLEDGE
    "sessionAcknowledgeMode" set to "CLIENT_ACKNOWLEDGE"(2): Automatic message acknowledgment after successful listener execution; no redelivery in case of exception thrown.
    "sessionAcknowledgeMode" set to "DUPS_OK_ACKNOWLEDGE"(3): Lazy message acknowledgment during or after listener execution; potential redelivery in case of exception thrown.

其实也是轮询模式(后台类似同步receive),轮询到消息则触发监听,而原版的MessageListener则是异步模式,底层收到消息则触发监听

重复消费

1
2
3
4
5
6
# 当onMessage方法没有成功执行完毕,比如抛出了异常,默认重复递送6次,即重复消费6次
jms.redeliveryPolicy.maximumRedeliveries=6

brokerUrl=tcp://192.168.103.171:61616?jms.redeliveryPolicy.maximumRedeliveries=0

brokerUrl=failover:(tcp://192.168.103.171:61616)?jms.redeliveryPolicy.maximumRedeliveries=0