spring框架测试
spring配置
<bean id="queueListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="demoQueueDestination" />
<property name="messageListener" ref="queueMessageListener" />
<property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE"/>
</bean>
测试代码
public class QueueMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
TextMessage textmessage = (TextMessage)message;
try {
System.out.println("接收到消息::"+ textmessage.getText());
System.out.println("接消息完毕!");
int i = 1/0; //人工异常
} catch (JMSException e) {
e.printStackTrace();
}
}
}
测试结果
ActiveMQ.Demo对列的MessagesEnqueued对列在生产者一发送消息时便变成15,且onMessage方法已接收到了消息,但MessagesDequeued一直是14,此条消息会重复接收6次,之后MessagesDequeued变成15,并且ActiveMQ.DLQ队列消息数加1。
⚠️与AUTO_ACKNOWLEDGE机制一样。
若没有int i = 1/0;也不调用message.acknowledge()
⚠️onMessage方法执行结束时,框架会自动调用message.acknowledge()
原生api
public static void main(String[] args) throws Exception {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER
, ActiveMQConnection.DEFAULT_PASSWORD
, ActiveMQConnection.DEFAULT_BROKER_URL);
conn = connectionFactory.createConnection();
// 事务性会话,自动确认消息
session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// 消息的目的地(Queue/Topic)
destination = session.createQueue(SUBJECT);
// destination = session.createTopic(SUBJECT);
// 消息的提供者(生产者)
consumer = session.createConsumer(destination);
conn.start();
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textmessage = (TextMessage)message;
try {
System.out.println("接收到消息::"+ textmessage.getText());
System.out.println("接消息完毕!");
} catch (JMSException e) {
}
try {
session.recover();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
当没有调用session.recover()和message.acknowledge()方法时,
ActiveMQ.Demo对列的MessagesEnqueued队列在生产者一发送消息时加1,MessagesDequeued不会增加,意味着并没有从对列中删除,消息没有被ack。
⚠️此时,消息并不会重发,若当前session与broker断开连接,此消息会重发给新连接的session。
当调用session.recover()方法时,没有被确认的消息会被重发六次
之后从ActiveMQ.Demo队列中删除,并被丢到ActiveMQ.DLQ队列中。