这是我在这里发表的第一篇文章,所以如果我不尊重格式规则,我会事先道歉 其他一般规则。
我有一个基于Spring JMS的客户端应用程序,它使用多个使用者从队列中读取。 我的约束是:在发生故障和消息重复检测的情况下保证重新发送。
Spring配置
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.DynamicDestinationResolver" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="MyConnectionFactory" />
<property name="destinationResolver" ref="jndiDestinationResolver" />
<property name="receiveTimeout" value="100" />
</bean>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="destinationResolver" ref="jndiDestinationResolver" />
<property name="connectionFactory" ref="MyConnectionFactory" />
<property name="destinationName" value="my_Queue" />
<property name="messageListener" ref="MyListener" />
<property name="maxConcurrentConsumers" value="10"/>
<property name="sessionTransacted" value="true"/>
</bean>
我的监听器代码类似于:
protected void processTextMessage(TextMessage textMessage) { try { // process message } catch(Exception e) { try { sendTextMessage("my_Queue",correlationID, textMessage.getText()); } catch (JMSException e1) { log.error("Error writing message back to the queue!"); throw JmsUtils.convertJmsAccessException(e1); } } } protected void sendTextMessage(String queueName, final byte[] correlationID, String message) { jmsTemplate.convertAndSend(queueName, message, new MessagePostProcessor() { public Message postProcessMessage(Message message) throws JMSException { message.setJMSCorrelationIDAsBytes(correlationID); return message; } }); }
我使用ActiveMQ进行了一些本地故障测试,并且重新发送正常(我注意到redelivered标志为false)。 我还试图在处理期间残酷地停止应用程序服务器,并且能够检查当前队列包含1个带有redelivered = true的消息。
这是实现目标的正确方法吗?
我希望这对于我将使用的JMS提供程序是透明的(在生产环境中使用Websphere MQ)。 目前我想避免通过抛出异常来回滚事务:我希望重新安排我失败的消息,就像队列中的新消息一样。 对于重复检测,我认为插入业务存在检查就足够了。
提前致谢并提出最好的问候
答案 0 :(得分:1)
是的,这是正确的方法。
答案 1 :(得分:0)
除当前( SUBMIT )队列外,拥有 ERROR 队列可能是更好的方法。
有几个原因:
如果来自源的信息无效,则可以更好地分析错误消息。 您可以在邮件头上具有MSG_PROCESSED_CNT属性,并根据需要使用它来重新处理邮件。当您在业务逻辑中进行外部集成时,它非常有用。
如果您的代码[try-block]因错误或集成问题而反复抛出异常会怎样?使用ERROR队列,您会看到深度上升,并可通过设置阈值监视器来通知问题。
将重新处理工作(非业务相关)委派给第三方应用程序。您的代码只包含您的业务逻辑。