我们正在尝试在客户端异常上实现重试机制。我们希望能够根据每条消息中的内容设置不同的路由密钥,ttl和重试计数。我们希望保持处理程序简单,即; for handleMessage抛出异常。我们如何处理此异常并使用适当的参数将消息发送到DLX。如果再次发生故障则重试 - 消息将被丢弃(确认),或者将在DLX上重新加载重试计数。我们在哪里实现这个逻辑以及如何连线?
========================
在加里的指导下,我能够实施。以下是摘录..
@Bean
public SimpleMessageListenerContainer listenerContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
jsonMessageHandler.setQueueName(queueName);
container.setQueueNames(queueName);
container.setMessageListener(jsonMessageListenerAdapter());
container.setAdviceChain(new Advice[]{retryOperationsInterceptor()});
return container;
}
@Bean
public MessageListenerAdapter messageListenerAdapter() {
return new MessageListenerAdapter(messageHandler,messageConverter);
}
@Bean
public MessageListenerAdapter jsonMessageListenerAdapter() {
return new MessageListenerAdapter(jsonMessageHandler);
}
@Bean
RetryOperationsInterceptor retryOperationsInterceptor() {
return RetryInterceptorBuilder.stateless().recoverer(republishMessageRecoverer).maxAttempts(1).build();
}
@Bean
RepublishMessageRecoverer republishMessageRecoverer() {
return new MyRepublishMessageRecoverer(rabbitTemplate());
}
==========
public class MyRepublishMessageRecoverer extends RepublishMessageRecoverer {
// - constructor
@Override
public void recover(Message message, Throwable cause) {
//Deal with headers
long currentCount = 0;
List xDeathList = (List)message.getMessageProperties().getHeaders().get("x-death");
if(xDeathList != null && xDeathList.size() > 0) {
currentCount = (Long)((Map)(xDeathList.get(0))).get("count");
}
if(currentCount < context.getRules().getNumberOfRetries()) {
//message sent to DLX
this.retryTemplate.send(handlerProperties.getSystem(), message);
} else {
//message ignored
}
throw new AmqpRejectAndDontRequeueException(cause);
}
}
答案 0 :(得分:3)
您无法修改被拒绝的消息,它将被路由到DLX / DLQ不变(除了x-death
标头由经纪人添加)。
如果要更改邮件属性,则必须自行重新发布到DLX / DLQ。
您可以使用Spring Retry with a customized RepublishMessageRecoverer执行此操作。