Я прочитал несколько ответов по этой теме, и кажется, что конфигурация, которая у меня есть, должна работать правильно, но по какой-то причине это не так.Маршрутизация мертвых букв в приложении Spring Boot
Вот конфиг:
@Bean Queue intakeQueue(String name) { return new Queue(name, true); }
@Bean Exchange dlx(String name) { return new DirectExchange(name); }
@Bean Queue dlq(String name) { return new Queue(name, false, false, true); }
@Bean
Binding dlb(Exchange dlx, Queue dlq, Queue reply) {
return BindingBuilder.bind(dlq).to(dlx).with(reply.getName()).noargs();
}
@Bean
Queue replyQueue(String name, Exchange dlx) {
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", dlx.getName());
args.put("x-dead-letter-routing-key", name);
return new Queue(name, true, false, false, args);
}
RabbitMQ UI показывает, что очередь имеет ответ DLX
и DLK
атрибуты.
Я отправлять сообщения как
this.rabbit.convertSendAndReceive(intakeQueue, obj, message -> {
message.getMessageProperties().setPriority(10);
return message;
});
обработчика сообщений бросает AmqpRejectAndDontRequeueException
сразу после того, как он получает сообщение. Это сделано специально для тестирования. Я начал с советов по повторной попытке, но поскольку он не дал никаких результатов, я упростил тестовый пример.
public Object handleMessage(Object obj) throws IOException {
throw new AmqpRejectAndDontRequeueException("Testing retries!");
}
Есть два вопроса, которые я вижу сейчас:
- сообщения никогда не показывает в DLQ после ARADRE была брошена. Это происходит, если я публикую в DLQ прямо с
handleMessage
. convertSendAndReceive
не получает обратно ничего (исключение может быть?) И ждет, пока не произойдет тайм-аут, который составляет 5 минут в моем случае. Это может быть предназначено, но для вызовов в стиле RPC это довольно странно.
Я пропустил или неправильно сконфигурировал что-то?
Хорошо, так что это DLQ для приема, а не для ответа. Наверное, меня смутили примеры, такие как 'FixedReplyQueueDeadLetterTests.java', где DLQ настроен для ответа. Я думаю, что я просто отправлю частично сериализованное исключение из регенератора сообщений, когда все попытки ответа исчерпаны. Возвращаемый объект вместо исключения из обработчика не будет запускать повторную попытку. Спасибо, это очень помогло, оно работает сейчас! –