RabbitMQ-Apache Camel чтение сообщений что делать с неудачными сообщениями

у меня есть следующее приложение PHP. Это публикует регистрацию пользователя в очереди сообщений. Приложение Java считывает данные из этой очереди и импортирует их. Надеюсь, на приведенной ниже диаграмме это будет видно. Я работаю только с Java-стороной вещей. Сообщения json уже существуют в очереди.

enter image description here

Маршрут (Потребляющая Сторона Java).

@Component
public class SignUpRouting {

  errorHandler(deadLetterChannel("rabbitmq://signUpDeadLetter.exchange?username=etc..").useOriginalMessage());

  from("rabbitmq://phpSignUp.exchange?username=etc....")
            .routeId("signUpRoute")
            .processRef("signUpProcessor")
            .end();
  //.... 

в процессор..

@Component
public class SignupProcessor implements Processor {

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    public void process(Exchange exchange) throws Exception {

        String json = exchange.getIn().getBody(String.class);
        SignUpDto dto = mapper.readValue(json, SignUpDto.class);

        SignUp signUp = new SignUp();
        signUp.setWhatever(dto.getWhatever());
        //etc....

        // save record
        signUpDao.save(signUp);
    }
}

мой вопрос таков.. что мне делать, когда процессор не может импортировать сообщение.

скажем, например, было исключение DAO. Поле данных могло быть toolong или импорт был в неправильном формате. Я не хочу потерять сообщение. Я хотел бы увидеть ошибку и повторить попытку импорта. Но я бы не хотел повторять сообщение каждые 30 секунд.

I я думаю, что мне нужно будет создать еще одну очередь.. Очередь мертвых писем и это неопределенно повторяет сообщение каждые 6 часов?.. Затем я бы просмотрел журналы, увидел ошибку и загрузил исправление, и сообщение было бы переработано?

как бы я это реализовал? Или я на неверном пути?

редактировать я попытался установить deadLetterExchange, чтобы увидеть, будет ли все в правильном направлении... Однако его ошибки и говорит, что очередь не может быть non null

 rabbitmq://phpSignUp.exchange?username=etc...&deadLetterExchange=signUpDeadLetter.exchange

2 ответов


вот пример использования заголовков мертвых букв:

        <from uri="rabbitmq://localhost/youexchange?queue=yourq1&amp;
            exchangeType=topic&amp;
            routingKey=user.reg.*&amp;
            deadLetterExchange=dead.msgs&amp;
            deadLetterExchangeType=topic&amp;
            deadLetterRoutingKey=dead.letters&amp;
            deadLetterQueue=dead.letters&amp;
            autoAck=false&amp;
            autoDelete=false"/>

          <!--We can use onException to make camel to retry, and after that, dead letter queue are the fallback-->
        <onException useOriginalMessage="true">
            <exception>java.lang.Exception</exception>
            <redeliveryPolicy asyncDelayedRedelivery="true" maximumRedeliveries="3" redeliveryDelay="5000"/>
        </onException>

нам нужно выключить autoAck и set deadLetterQueue, затем, если возникает исключение, сообщение будет находиться в очереди мертвых букв. Чтобы использовать onException, мы можем контролировать повторную попытку, прежде чем camel отбросит сообщение в очередь мертвых писем.


вы можете использовать onException для перехвата исключений, если есть исключение, сообщение будет маршрутом к обмену мертвыми буквами, вот пример в Spring DSL:

<onException useOriginalMessage="true">
            <exception>java.sql.SQLException</exception>
            <redeliveryPolicy asyncDelayedRedelivery="true" maximumRedeliveries="1" redeliveryDelay="1000"/>

            <inOnly uri="rabbitmq://localhost/dead.msgs?exchangeType=fanout&amp;
                    autoDelete=false&amp;
                    bridgeEndpoint=true"/>
</onException>