JMS消息确认模式

来源:互联网 发布:青牛软件怎么样 编辑:程序博客网 时间:2024/06/06 01:36

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

 

一 事务性会话

在事务性会话中,当一个事务被提交的时候,确认自动发生;即只需设置Session.SESSION_TRANSACTED。

一般而言,在创建事务性Session的时候:

Connection.createSession(是否支持事务,应答模式)

如果第一个参数设置为true,即事务性会话,那么不需要显示设置第二个参数: 应答模式.

Session.SESSION_TRANSACTED,因为创建会话的第一个参数设置为true,就代表着应答模式为Session.SESSION_TRANSACTED,而且第二个参数也没有意义,可以忽略此参数,比如你设置成了AUTO_ACKNOWLEDGE,对于会话来说没有任何意义,因为会被忽略。

如何提交会话?

Session.commit();

测试:

产生消息:

public classMessageSender {
    public staticvoid main(String[]args) throws JMSException {
        ConnectionFactoryconnectionFactory= new ActiveMQConnectionFactory("tcp://192.168.3.200:61616");
        Connection connection= connectionFactory.createConnection();
        connection.start();
        Session session= connection.createSession(Boolean.TRUE,Session.SESSION_TRANSACTED);
        Destination dest= session.createQueue("animals");
        MessageProducerproducer= session.createProducer(dest);
        MapMessage message= null;
        for (int i = 1; i <= 6; i++) {
            message = session.createMapMessage();
            message.setIntProperty("ackCode",Session.CLIENT_ACKNOWLEDGE);
            message.setString("MSG---"+ i, "Product ID---"+i);
            producer.send(message);
        }
        session.close();
        connection.close();
    }
}

我们并没有提交消息,那么我们查看是否产生了6条消息


如果我们调用Session,commit();结果呢?这下肯定就有了。



二 非事务性会话

在非事务性会话中,消息何时被确认取决于创建会话的应答模式---

acknowledgement

 

Acknowledgement模式有三个可选值:

# AUTO_ACKNOWLEDGE

当客户端成功接受到消息,就会自动确认收到消息,比如receive方法或者MessageListener.onMessage方法,这方式就是一条消息确认一次。

public class MessageReciver {    public static void main(String[] args) throws JMSException {        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.3.201:61616");        Connection connection = connectionFactory.createConnection();        connection.start();        Session session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);        Destination destination = session.createQueue("animals");        MessageConsumer consumer = session.createConsumer(destination);        int i = 0;        MapMessage message = null;        while (i < 6) {            i++;            message = (MapMessage) consumer.receive();            System.out.println("消息: "+message.getString("MSG---" + i));        }        session.close();        connection.close();    }}

 

# CLIENT_ACKNOWLEDGE

客户端必须通过Message明确调用acknowledge方法确认收到消息

public class MessageReciver {    public static void main(String[] args) throws JMSException {        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.3.201:61616");        Connection connection = connectionFactory.createConnection();        connection.start();        Session session = connection.createSession(Boolean.FALSE,Session.CLIENT_ACKNOWLEDGE);        Destination destination = session.createQueue("animals");        MessageConsumer consumer = session.createConsumer(destination);        int i = 0;        MapMessage message = null;        while (i < 6) {            i++;            message = (MapMessage) consumer.receive();            System.out.println("消息: "+message.getString("MSG---" + i));            message.acknowledge();        }        session.close();        connection.close();    }}

 

# DUPS_OK_ACKNOWLEDGE

延迟确认提交,可能存在重复的提交。比如客户端接受了10条消息,并且已经处理了,但是因为延迟提交了,所以JMS服务端可能还没有确认。这时候假设JMS 服务器宕机,那么重启之后,可能会因为之前没有提交的消息会进行重新发送,就导致重复发送的问题。

一般重新发送会设置一个消息头:JMSRedelivered设置为true