Spring AMQP RPC使用者并引发异常

时间:2018-11-13 10:26:39

标签: exception rabbitmq spring-amqp

我有一个使用RPC模式的使用者(RabbitListner),我想知道是否有可能引发发布者可以处理的异常。

为更清楚地说明我的情况,情况如下:

  • 发布者以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. 将bean定义为配置文件:

    @配置 公共类RabbitConfig扩展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是我先前定义的bean:

    @Override
    @RabbitListener(queues = "${rabbit.queue}"
        , errorHandler = "rabbitErrorHandler"
        , returnExceptions = "true")
     public ReturnObject receiveMessage(Message message) {
    
  4. 对于RabbitTemplate,我设置此属性:

       rabbitTemplate.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
    

当消息受到消费者的威胁,但发送了错误消息时,我获得了一个RemoteInvocationResult,该结果包含原始异常到e.getCause()。getCause()中。

2 个答案:

答案 0 :(得分:1)

请参见returnExceptions上的@RabbitListener属性(自2.0开始)。 Docs here

  

returnExceptions属性为“ true”时,将导致异常返回给发送者。异常包装在RemoteInvocationResult对象中。

     

在发送方,有一个可用的RemoteInvocationAwareMessageConverterAdapter,如果配置为RabbitTemplate,它将重新引发服务器端异常,并包装在AmqpRemoteException中。服务器异常的堆栈跟踪将通过合并服务器和客户端堆栈跟踪进行综合。

     

重要

     

该机制通常仅适用于使用Java序列化的默认SimpleMessageConverter;例外通常不是“杰克逊友好型”的,因此无法序列化为JSON。如果使用的是JSON,请考虑在引发异常时使用errorHandler返回其他一些Jackson友好的Error对象。

答案 1 :(得分:0)

您必须将一条消息作为错误返回,使用方可以选择将其视为异常。但是,我认为正常的异常处理流程不适用于消息传递。您的发布应用程序(RPC服务的使用者)需要知道可能出问题的地方,并对其进行编程以应对这些可能性。