我尝试像这样在mycode中使用StatefulRetryOperationsInterceptor:
@Bean
public StatefulRetryOperationsInterceptor statefulRetryOperationsInterceptor(){
return RetryInterceptorBuilder.stateful()
.maxAttempts(5)
.backOffOptions(1000,2.0,10000)
.build();
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
logger.info("==> custom rabbitmq Listener factory:"+ connectionFactory);
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setConcurrentConsumers(3);
factory.setMaxConcurrentConsumers(10);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
factory.setPrefetchCount(200);
factory.setAdviceChan(new Advice[]{
statefulRetryOperationsInterceptor()
}) //add retry
return factory;
}
我的代码运行良好,但是当使用者中有异常时,根本不会重试。 那么如何使用StatefulRetryOperationsInterceptor?该类用于捕获异常并重新发送吗?
如果发生Exception,我想重新排队并再次发送给消费者5次,然后将消息发送到死队列,如何更优雅地使用amqp?
根据@Gary Russell的回答,我使用redis记录异常,是否有像StatefulRetryOperationsInterceptor这样的方法可以使操作更优雅?
try {
receiveMessage(message);
channel.basicAck(deliveryTag, false);
redisTemplate.opsForHash().delete(MQConstants.MQ_CONSUMER_RETRY_COUNT_KEY, messageProperties.getMessageId());
}
catch (Exception e) {
if (consumerCount >= MQConstants.MAX_CONSUMER_COUNT) {
channel.basicReject(deliveryTag, false);
} else {
redisTemplate.opsForHash().increment(MQConstants.MQ_CONSUMER_RETRY_COUNT_KEY,
messageProperties.getMessageId(), 1);
Thread.sleep((long) (Math.pow(MQConstants.BASE_NUM, consumerCount)*1000));
channel.basicNack(deliveryTag, false, true);
}
}
答案 0 :(得分:1)
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
由于您使用的是手动挡板,因此您可以自己操作;容器无法帮助您。您需要对状态重试使用AUTO或使用channel.basicReject()
进行重新排队。