Estoy empezando a darme cuenta de cómo funciona JMS ActiveMQ Acknowledgements
en Spring. Hasta ahora, tengo un consumidor que funciona a la perfección, con la excepción de que cuando no reconozco el mensaje, todavía se saca de la cola (espero que permanezca allí o termine en una cola de letra muerta).Obteniendo un simple cliente Spring JMS confirme que trabaja
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">
<!-- A JMS connection factory for ActiveMQ -->
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
p:brokerURL="failover://(tcp://jms1:61616,tcp://jms2:61616)?randomize=false&jms.redeliveryPolicy.maximumRedeliveries=5" />
<!-- A POJO that implements the JMS message listener -->
<bean id="simpleMessageListener" class="com.company.ConsumerClass" />
<!-- A JMS namespace aware Spring configuration for the message listener container -->
<jms:listener-container
container-type="default"
connection-factory="connectionFactory"
acknowledge="client"
concurrency="10-50"
cache="consumer">
<jms:listener destination="someQueue" ref="simpleMessageListener" method="onMessage" />
</jms:listener-container>
</beans>
En el ConsumerClass, mi sencilla consumidor se ve algo como esto:
@Override public final void onMessage(Message message) {
Object postedMessage = null;
try {
postedMessage = ((ObjectMessage) message).getObject();
if (postedMessage.getClass() == SomeMessageType.class) {
try {
//Some logic here
message.acknowledge();
return; //Success Here
} catch (MyException e) {
logger.error("Could not process message, but as I didn't call acknowledge I expect it to end up in the dead message queue");
}
}
} catch (JMSException e) {
logger.error("Error occurred pulling Message from Queue", e);
}
//Also worth noting, if I throw new RuntimeException("Aww Noos"); here then it won't take it from the queue, but it won't get consumed (or end up as dead letter)...
}
Lo siento, en este caso es exitoso si regreso después del mensaje.acknowledge() (he añadido esto en el ejemplo de código) –
Además, si elimino el comentario del lanzamiento RuntimeException (tiene que ser el tiempo de ejecución para satisfacer la interfaz MessageListener) Obtengo un error: 08: 39: 59,066 WARN org.springframework.jms.listener.DefaultMessageListenerContainer # 0-2 listener.DefaultMessageListenerContainer: 694 - Falló la ejecución de la escucha del mensaje JMS y no se ha configurado ErrorHandler. java.lang.RuntimeException: Aww Noos Veo que en este caso los mensajes se mantienen con el consumidor hasta que lo termine, en ese momento intentarán consumir a otro consumidor haciéndome pensar que acknowledge = " cliente "no hace nada –
En realidad, si leo el derecho javadoc," auto "reconocerá ANTES de que se llame al oyente: " sessionAcknowledgeMode "puesto a" AUTO_ACKNOWLEDGE "(predeterminado): reconocimiento automático de mensajes antes de la ejecución del oyente; no se vuelve a entregar en caso de excepción lanzada. " – dstibbe