【发布时间】:2014-02-26 10:16:23
【问题描述】:
有一个类 'MyConsumer' 从队列接收消息并处理它们。有两个要求:
- 如果有消息包含无效内容,MyConsumer 不应确认,但可以处理以后的消息
- MyConsumer 重启后,未消费的消息将再次投递
我尝试使用 spring-jms,支持 listener-container,但找不到符合第一个要求的解决方案。
我的代码:
<amq:queue id="destination" physicalName="org.springbyexample.jms.test"/>
<amq:connectionFactory id="jmsFactory" brokerURL="tcp://localhost:11111"/>
<bean id="jmsConsumerConnectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory"
p:targetConnectionFactory-ref="jmsFactory"/>
<bean id="jmsConsumerTemplate" class="org.springframework.jms.core.JmsTemplate"
p:connectionFactory-ref="jmsConsumerConnectionFactory"
p:defaultDestination-ref="destination"/>
<bean id="jmsMessageListener" class="test.MyConsumer"/>
<bean id="errorHandler" class="test.MyErrorHandler"/>
<jms:listener-container container-type="default"
connection-factory="jmsConsumerConnectionFactory"
error-handler="errorHandler"
acknowledge="client">
<jms:listener destination="org.springbyexample.jms.test" ref="jmsMessageListener"/>
</jms:listener-container>
班级MyConsumer:
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("!!!!!!!!! get message: " + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
if (theNumberOfMessageIs(3)) {
throw new RuntimeException("something is wrong");
}
}
你可能注意到listener-container中的acknowledge是client,实际上它有3个值:
- 自动(默认)
- 客户
- 已成交
我尝试了所有这些,但没有一个符合我的要求。我的测试场景:
- 生产者将 3 条消息放入队列
- 启动一个线程来监控队列中的消息计数,当计数发生变化时,打印出来
- 启动消费者,它将接收来自队列的消息,并处理它们
- 稍等片刻,将另外 3 条消息放入队列
对于auto:
MyConsumer 在收到每条消息后都会确认,无论是否抛出异常
对于client:
只有在onMessage 中没有抛出异常时,MyConsumer 才会确认。对于第 3 条消息,它会抛出异常,队列中会有一条消息未消费。但是当它得到第 4 条消息并且没有抛出异常时,队列中的第 3 条消息将消失
对于transacted:
如果在 MyConsumer 中抛出异常,消息将不会被确认并被重新发送多次。之后,消息从队列中消失
但没有一个符合要求1。
我想知道:我是否需要寻找除Spring-jms之外的其他解决方案,或者我的用法不正确?
【问题讨论】:
-
嗨@Freewind,你达到你的要求了吗?
标签: java jms spring-jms