在Sprint Boot中更改嵌入式ActiveMQ的Active MQ RedeliveryPolicy

时间:2017-10-05 15:57:53

标签: spring-boot activemq spring-jms

如何在使用Spring Boot时更改嵌入式ActiveMQ的重新传递策略?我尝试在DefaultJmsListenerContainerFactory上指定FixedBackOff,但它没有帮助。下面是我用来初始化jms工厂bean的代码。我有一个消息使用者处理队列上的传入消息。在处理期间由于资源不可用,我抛出一个已检查的异常。我希望在固定的时间间隔之后重新传递消息以进行处理。

Spring Boot:1.5.7。发布

Java:1.7

@Bean
public JmsListenerContainerFactory<?> publishFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = 
        new DefaultJmsListenerContainerFactory();

    factory.setBackOff(new FixedBackOff(5000, 5));

    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);

    // You could still override some of Boot's default if necessary.
    factory.setErrorHandler(new ErrorHandler() {

        @Override
        public void handleError(Throwable t) {
            LOG.error("Error occured in JMS transaction.", t);
        }

    }); 
    return factory;
}

消费者代码:

@JmsListener(destination = "PublishQueue", containerFactory = "publishFactory")
@Transactional
public void receiveMessage(PublishData publishData) {
    LOG.info("Processing incoming message on publish queue with transaction id: " + publishData.getTransactionId());

    PublishUser user = new PublishUser();
    user.setPriority(1);
    user.setUserId(publishData.getUserId());

    LOG.trace("Trying to enroll in the publish lock queue for user: " + user);
    PublishLockQueue lockQueue = publishLockQueueService.createLock(user);
    if (lockQueue == null)
        throw new RuntimeException("Unable to create lock for publish");
    LOG.trace("Publish lock queue obtained with lock queue id: " + lockQueue.getId());

    try {
        publishLockQueueService.acquireLock(lockQueue.getId());
        LOG.trace("Acquired publish lock.");
    }
    catch (PublishLockQueueServiceException pex) {
        throw new RuntimeException(pex);
    }

    try {
        publishService.publish(publishData, lockQueue.getId());
        LOG.trace("Completed publish of changes.");

        sendPublishSuccessNotification(publishData);
    }
    finally {
        LOG.trace("Trying to release lock to publish.");
        publishLockQueueService.releaseLock(lockQueue.getId());
    }

    LOG.info("Publish has been completed for transaction id: " + publishData.getTransactionId());
}

1 个答案:

答案 0 :(得分:0)

@claus回答:我测试了它的工作原理:

  

作为消费者,您需要使用事务处理确认模式让消费者回滚异常,并让ActiveMQ能够在运行多个消费者时将消息重新传递给同一个消费者或其他消费者。但是,你可以在ActiveMQ上配置重新传递选项,例如退避等。上面的错误处理程序只是一个noop监听器,除了记录之外它不能做很多事情