fly*_*ire 5 java spring activemq-classic jms
我正在使用 spring-jms 和 active mq。
我ErrorHandler
设置了一个侦听器,每次 jms 消息传递失败时都会接收回调 - 即处理消息的方法抛出异常而不是优雅地返回。
但是,我的 jms 配置为重试多次,直到 jms 交付最终成功。我的回调会收到所有失败的通知。
我想要的是一个侦听器,仅当所有重试最终失败时才收到通知。动机是提出问题以引起管理员的注意。但我不希望管理员控制台中出现虚假通知。
<bean abstract="true" id="abstractDestinationListener"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsFactory" />
<property name="errorHandler" ref="destinationErrorHandler"/>
<property name="sessionTransacted" value="true"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
您可以考虑两种选择:
1. 与消费者进行 DLQ
对有问题的目的地使用每个目的地的死信队列 ( individualDeadLetterStrategy
- https://activemq.apache.org/message-redelivery-and-dlq-handling.html )。当达到最大重新传递计数时,消息将移出到 DLQ。然后,您可以在该队列上设置一个使用者,并使用向管理员发送电子邮件的侦听器。
2. 超出最大重新传递计数时不要抛出异常
用 try-catch 封装监听器,仅当尚未达到最大重新传递计数时才重新抛出任何异常;否则发送电子邮件:
@Value("${config.max-redelivery-count}")
private String maxRedeliveryCount;
@JmsListener(destination = "..")
public void onMessage(Message message) throws JMSException {
boolean isLastAttempt = message.getIntProperty("JMSXDeliveryCount") > maxRedeliveryCount;
try {
// do normal flow
} catch (Exception e) {
if (isLastAttempt) {
sendEmail(..);
} else {
throw e;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,该选项意味着将重新交付限制放置在两个位置 - 代理配置和代码。