jms 错误处理程序:仅当 jms 放弃时接收回调

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)

Jak*_*rab 3

您可以考虑两种选择:

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)

但是,该选项意味着将重新交付限制放置在两个位置 - 代理配置和代码。