Spring JMS -忽略指数消息重新交付策略

aoyhnmkz  于 2023-05-27  发布在  Spring
关注(0)|答案(2)|浏览(130)

我们正在尝试使用spring jms为ActiveMQ设置重新交付策略。我们已经为重新交付设置了指数回退,但它似乎被忽略了-消息重新交付之间的间隔是固定的,而不是指数增长。
有谁知道可能是什么问题吗?这是我们的spring-jms配置:

<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
    p:brokerURL="${activemq_url}">
    <property name="redeliveryPolicy" ref="redeliveryPolicy" />
</bean>

<bean id="redeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
    <property name="queue" value="*" />
    <property name="initialRedeliveryDelay" value="10000" />
    <property name="redeliveryDelay" value="10000" />
    <property name="maximumRedeliveries" value="-1" />
    <property name="useExponentialBackOff" value="true" />
    <property name="backOffMultiplier" value="5" />
</bean>

<bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory" 
    p:targetConnectionFactory-ref="connectionFactory" p:sessionCacheSize="10" 
    />

<!-- A JmsTemplate instance that uses the cached connection and destination -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="messageConverter" ref="messageConverter" />
    <property name="sessionTransacted" value="true" />
</bean>

<!-- The Spring message listener container configuration -->
<jms:listener-container container-type="default"
    destination-type="queue" connection-factory="connectionFactory"
    acknowledge="transacted" concurrency="1" cache="consumer">
    <jms:listener destination="testQueue" ref="testService"
        method="onMessage" />
</jms:listener-container>

谢谢!

**编辑:**这是一个日志示例,每5秒重传一次:

11 May 2014 18:52:00  WARN DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: Sun May 11 18:52:00 IDT 2014
at ...
11 May 2014 18:52:05  WARN DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: Sun May 11 18:52:05 IDT 2014
at ...
11 May 2014 18:52:10  WARN DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: Sun May 11 18:52:10 IDT 2014
at ...
11 May 2014 18:52:15  WARN DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: Sun May 11 18:52:15 IDT 2014
at ...
11 May 2014 18:52:20  WARN DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
javax.jms.JMSException: Sun May 11 18:52:20 IDT 2014
at ...
4uqofj5v

4uqofj5v1#

我想我找到问题了:当我之前测试策略时,我抛出JMSException来获取要重新传递的消息。
一个我改变了抛出的异常到Exception/RuntimeException,指数回退工作。
我不知道为什么JMSException会导致指数回退策略被忽略……有人有什么想法吗?

ttvkxqim

ttvkxqim2#

为了让@tyfyh的评论更突出一点,让我们将其扩展为一个答案。通过该高速缓存级别设置为CACHE_CONSUMER,这意味着JMS消费者(消息接收者)被缓存,从而允许将其重用于多个消息传递。这种缓存行为可能会影响重新交付行为和异常处理,并修复上述问题。
您可以自己定义DefaultJmsListenerContainerFactory:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(PlatformTransactionManager txManager, ConnectionFactory connectionFactory) {
  var factory = new DefaultJmsListenerContainerFactory();
  factory.setTransactionManager(txManager);
  factory.setConnectionFactory(connectionFactory);
  factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);

  return factory;
}

或者使用现有的bean并设置该高速缓存级别:

@Configuration
public class JmsListenerConfig {

  private final DefaultJmsListenerContainerFactory factory;

  public JmsListenerConfig(DefaultJmsListenerContainerFactory factory) {
    this.factory = factory;
  }

  @PostConstruct
  public void customizeJmsListenerContainerFactory() {
    factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
  }
}

相关问题