【问题标题】:RabbitMQ infinite loop issueRabbitMQ 无限循环问题
【发布时间】:2021-09-11 17:43:09
【问题描述】:

我在使用 rabbitMQ 将消息从服​​务 A 发送到服务 B 时遇到问题,该服务还向服务 C 发送通知,问题是,我必须将 @RabbitListener 和 Rabbittemplate 放在相同的方法中,如下所示:

@Autowired private RabbitTemplate template;

@RabbitListener(queues=RabbitConfig.QUEUETD)
public ResponseEntity<String> AddSas_Campaign(SasCampaign sasCampaign){
        if
     //...
     template.convertAndSend(RabbitConfig.EXCHANGE,RabbitConfig.ROUTING_KEY,sasCampaign);

     return new ResponseEntity<String>( "New line inserted ", HttpStatus.OK);}
     //...
     }
     else return new ResponseEntity<String>("Campaign Code exists",HttpStatus.OK);
     
}

它正在不断地创建和无限循环(+2000/分钟)消息和异常。

2021-06-29 14:34:16,560 WARN  [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler: Execution of Rabbit message listener failed.
org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1746)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1636)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1551)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1539)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1530)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1474)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:967)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1288)
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1194)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.amqp.rabbit.listener.adapter.ReplyFailureException: Failed to send reply with payload 'InvocationResult [returnValue=<200 OK OK,Test SasCamapign inserted ,[]>, returnType=org.springframework.http.ResponseEntity<java.lang.String>, bean=tn.itserv.services.Sas_CampaignService@4232ecc, method=public org.springframework.http.ResponseEntity tn.itserv.services.Sas_CampaignService.AddSas_Campaign(tn.itserv.entities.SasCampaign)]'
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.doHandleResult(AbstractAdaptableMessageListener.java:476)
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.handleResult(AbstractAdaptableMessageListener.java:400)
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:152)
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:135)
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1632)
    ... 10 common frames omitted
Caused by: org.springframework.amqp.AmqpException: Cannot determine ReplyTo message property value: Request message does not contain reply-to property, and no default response Exchange was set.
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.getReplyToAddress(AbstractAdaptableMessageListener.java:576)
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.doHandleResult(AbstractAdaptableMessageListener.java:472)
    ... 14 common frames omitted

说实话,我还没有 100% 理解它是如何工作的,我应该为每个交换创建不同的队列吗?因为它部分工作(从服务 A 到 B 或从 B 到 C)但是当我同时使用它时,它会创建这些异常。

【问题讨论】:

  • 我在生产中遇到过类似的问题,每年都会出现几次。 “失败时重新排队”的概念似乎是个坏主意,但这是以前的开发人员实现的。
  • 第一次使用rabbitMQ,有没有找到问题的解决方法或者原因呢。
  • 原因是消息在异常时被放回队列中。要修复它,您不会从 RabbitListener 抛出异常。尝试使用 try catch 包围并返回带有服务器错误的响应实体。

标签: spring-boot rabbitmq microservices


【解决方案1】:

所以我意识到@RabbitListener 函数应该没有返回值,这意味着void 而不是我的ResponseEntity 所以我的想法是创建一个调用我的方法并且没有返回值的新方法:

@RabbitListener(queues=RabbitConfig.QUEUETD)
public void receiveFromService(SasCampaign sasCampaign){
    AddSas_Campaign(sasCampaign);
}

【讨论】:

    【解决方案2】:

    我在生产中遇到过类似的问题,每年都会出现几次。 “失败时重新排队”的概念似乎是个坏主意,但这是以前的开发人员实现的。

    原因是消息在异常时被放回队列中。要修复它,您不会从 RabbitListener 抛出异常。尝试使用 try catch 包围并返回带有服务器错误的响应实体。

    @Autowired private RabbitTemplate template;
    
    @RabbitListener(queues=RabbitConfig.QUEUETD)
    public ResponseEntity<String> AddSas_Campaign(SasCampaign sasCampaign){
         try {
            if
            //...
            template.convertAndSend(RabbitConfig.EXCHANGE,RabbitConfig.ROUTING_KEY,sasCampaign);
    
            return new ResponseEntity<String>( "New line inserted ", HttpStatus.OK);}
           //...
           }
           else return new ResponseEntity<String>("Campaign Code exists",HttpStatus.OK);
         
       } catch(Exception e) {
          return new ResponseEntity<String>("Error on Message Processing", HttpStatus.INTERNAL_SERVER_ERROR);
       }
    }
    

    【讨论】:

    • 我试过你的方法,但它没有用我的意思是现在异常没有显示但无限循环仍然存在,出于某种原因,我认为 ResponseEntity 是我删除它的问题,它有点作品我不知道为什么,它是否将其视为回复消息?
    • 好的 - 我还没有解决这个问题 - 我只是通过进程容忍它。
    • 在某处没有 RabbitMQ 的 'requeue on error' 配置吗?
    • 不,不是真的在使用非常基本的配置
    • 很明显,用@RabbitListener 注释的方法应该有 void 作为返回,这意味着我必须找到一个解决方法
    猜你喜欢
    • 1970-01-01
    • 2014-09-03
    • 2021-09-02
    • 2020-09-09
    • 2018-09-24
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多