2016-09-09 8 views
0

Я делаю следующие шаги:Spring Кролик: режим Признайте = Ручной с RetryTemplate не удаляет сообщение из очереди

  1. MessageListener получает сообщение из очереди Q1
  2. Сверяет сообщение
  3. Если проверка сбой, вызовите channel.basicReject() и переместите его в очередь мертвых букв.
  4. Остается, скажем, сервер электронной почты не работает. Я вызываю channel.basicReject() с запросом true и генерирую исключение. Он отправляется на шаблон повтора и после maxAttempts восстанавливается (RepublishMessageRecoverer) и переходит в очередь мертвых букв.

Но оно не удаляет сообщение из Q1.

public void onMessage(Message message, Channel channel) throws Exception { 
     try { 
      validateMessage(); 

      processMessage(message); 
      channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); 
     } 
     catch (DataValidationException ex){ 
      channel.basicReject(message.getMessageProperties().getDeliveryTag(),false); 

     } 
     catch(DownstreamAppException ex) { 
      channel.basicReject(message.getMessageProperties().getDeliveryTag(),true); 
      throw ex; 
     } 
    } 

    void validMessage() { 
     .. 
     throw new DataValidationException(); 
    } 

    void processMessage() { 

     ... 
     throw new DownstreamAppException(); 
    } 

Я не хочу, чтобы снова поставить сообщения, которые прошли проверку, но хотят, чтобы снова поставить те, которые не были обработаны из-за какой-то вниз по течению сбоя приложения для повторных попыток.

Несколько вопросов: 1. Если я не делаю исключение в catch OutstreamAppException, сообщение не идет throw retryTemplate и recoverer. Это потому, что пересылка отклоненного сообщения является новым сообщением?

  1. Почему сообщение не удалено из Q1? и как я могу это исправить?

Благодаря

ответ

0

Вы ответственны за ACKing при использовании ручных подтверждений (независимо от повторных попыток). Если ваш код никогда не будет защищен, сообщение будет (в конце концов) запрошено; но у вас нет доступа к каналу в восстановителе.

Реальный вопрос, почему вы используете руководство acks и ChannelAwareMessageListener? Ваш пример использования прост. Используя AUTO ackmode, контейнер подтвердит сообщение об успехе и отклонит его в любом исключении.

Поскольку регенератор переиздает сообщение, это считается успешным, и сообщение будет передано контейнером.

Чтобы выборочно повторить/потребовать, вам понадобится настраиваемый обработчик ошибок, см. this answer for more information.

+0

Также см. [Этот ответ] (http://stackoverflow.com/questions/39272648/spring-amqp-enable-retry-by-configuration-and-prevent-it-according-to-a-specifie/39272873# 39272873). –

 Смежные вопросы

  • Нет связанных вопросов^_^