Spring AMQP RPC потребитель и выбросить исключение - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть потребитель (RabbitListner) в режиме RPC, и я хотел бы знать, возможно ли выдать исключение, которое может быть обработано издателем.

Чтобы прояснить мое объяснение, случай таков:следуйте:

  • Издатель отправляет сообщение в режиме RPC
  • Потребитель получает сообщение, проверяет действительность сообщения иесли сообщение не может быть учтено из-за отсутствующих параметров, то я бы хотел сгенерировать исключение .Исключением может быть конкретное бизнес-исключение или конкретное AmqpException, но я хочу, чтобы издатель мог обработать это исключение, если оно не прошло по тайм-ауту.

Я пытаюсь использовать AmqpRejectAndDontRequeueException , но мой издатель не получает исключение, а только пустой ответ.

Возможно ли это сделать, или, может быть, это плохая практика для реализации такого рода?

РЕДАКТИРОВАТЬ 1:

После ответа @GaryRussel вот решение моего вопроса:

  1. Для RabbitListner я создаю обработчик ошибок:

     @Configuration
     public class RabbitErrorHandler implements         RabbitListenerErrorHandler {
     @Override public Object handleError(Message message, org.springframework.messaging.Message<?> message1, ListenerExecutionFailedException e) {
    throw e;
    }
    

    }

  2. Определить компонент в файл конфигурации:

    @ Открытый класс конфигурации RabbitConfig extends RabbitConfiguration {

    @Bean
    public RabbitTemplate getRabbitTemplate() {
        Message.addWhiteListPatterns(RabbitConstants.CLASSES_TO_SEND_OVER_RABBITMQ);
    return new RabbitTemplate(this.connectionFactory());
    

    }

    /**
    * Define the RabbitErrorHandle
    * @return Initialize RabbitErrorHandle bean
    */
    @Bean
    public RabbitErrorHandler rabbitErrorHandler() {
       return new RabbitErrorHandler();
    }
    }
    
  3. Создайте @RabbitListner с параметрами, где rabbitErrorHandler - это компонент, который я определил ранее:

    @Override
    @RabbitListener(queues = "${rabbit.queue}"
        , errorHandler = "rabbitErrorHandler"
        , returnExceptions = "true")
     public ReturnObject receiveMessage(Message message) {
    
  4. ДляRabbitTemplaт. е. я устанавливаю этот атрибут:

       rabbitTemplate.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
    

Когда сообщение рассылается потребителем, но отправляет ошибку, я получаю RemoteInvocationResult, который содержит исходное исключение в e.getCause ().getCause ().

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

См. Свойство returnExceptions в @RabbitListener (с версии 2.0). Документы здесь .

Атрибут returnExceptions, когда true приведет к тому, что исключения будут возвращены отправителю.Исключение заключено в объект RemoteInvocationResult.

На стороне отправителя имеется доступный RemoteInvocationAwareMessageConverterAdapter, который при настройке в RabbitTemplate перезапустит исключение на стороне сервера, заключенное в AmqpRemoteException.Трассировка стека исключений сервера будет синтезирована путем объединения трассировок стека сервера и клиента.

Важное

Этот механизм обычно работает только со стандартным SimpleMessageConverter, которыйиспользует сериализацию Java;исключения, как правило, не «дружелюбны к Джексону», поэтому их нельзя сериализовать в JSON.Если вы используете JSON, рассмотрите возможность использования errorHandler для возврата другого дружественного Джексону объекта Error при возникновении исключения.

0 голосов
/ 13 ноября 2018

Вы должны вернуть сообщение как ошибку, которую приложение-потребитель может рассматривать как исключение.Тем не менее, я не думаю, что нормальные потоки обработки исключений применимы к обмену сообщениями.Вашему издательскому приложению (потребителю службы RPC) необходимо знать, что может пойти не так, и запрограммировать его на использование этих возможностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...