Listener method 'no match' threw exception
刷屏java
2020-03-26 11:00:07.747 [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#1-1] WARN org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.log(117) - Execution of Rabbit message listener failed. org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener method 'no match' threw exception at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:204) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:129) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1542) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1468) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1456) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1451) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1400) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:870) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:854) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:78) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1137) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1043) at java.lang.Thread.run(Thread.java:748) Caused by: org.springframework.amqp.AmqpException: No method found for class [B at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getHandlerForPayload(DelegatingInvocableHandler.java:149) at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.invoke(DelegatingInvocableHandler.java:129) at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:61) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:196) ... 12 common frames omitted 複製代碼
先上個人代碼:spring
@Slf4j @Component @RabbitListener(queues = "mall.order.cancel") public class CancelOrderReceiver { @Autowired private OmsPortalOrderService portalOrderService; @Resource private CancelOrderSender cancelOrderSender; @RabbitHandler public void handler(Long orderId){ try { log.info("process orderId:{}", orderId); portalOrderService.cancelOrder(orderId); } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); // 異常處理 cancelOrderSender.sendFailedMessage(orderId); } } } 複製代碼
爲何會出現方法未匹配呢?緣由在@RabbitListener
身上,當此註解放到類上時,會根據數據類型去匹配@RabbitHandler
註解的方法,個人handler
方法入參是Long
類型,若是傳入的是String
類型就會報Listener method 'no match' threw exception
了,找到了問題(RabbitMQ的requeue機制),下面給出解決方法:bash
再增長一個handler(String orderId)
方法,不管傳入的是Long
型仍是String
型都會獲得處理,這種方式比較笨,不推薦使用markdown
將@RabbitListener
註解放到方法上,以下代碼:oop
@Slf4j @Component public class CancelOrderReceiver { @Autowired private OmsPortalOrderService portalOrderService; @Resource private CancelOrderSender cancelOrderSender; @RabbitHandler @RabbitListener(queues = "mall.order.cancel") public void handler(Long orderId){ try { log.info("process orderId:{}", orderId); portalOrderService.cancelOrder(orderId); } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); // 異常處理 cancelOrderSender.sendFailedMessage(orderId); } } } 複製代碼
這樣不管你傳入的數據類型是什麼,都會進入此方法,不用擔憂刷屏了。固然若是傳入的類型不匹配,也會報錯的。因此要與消費發送者約束好數據類型是很是有必要的。學習
將rabbitmq
的「requeue」配置爲false
。這種方式簡單粗暴,但異常很差捕獲,後續的異常處理難進行spa
Listener method '***' threw exception
刷屏code
2020-03-26 11:46:22.789 [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] WARN org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler.log(117) - Execution of Rabbit message listener failed. org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener method 'public void com.macro.mall.portal.component.CancelOrderReceiver.handler(java.lang.Long)' threw exception at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:204) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:129) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1542) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1468) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1456) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1451) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1400) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:870) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:854) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:78) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1137) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1043) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.NumberFormatException: For input string: "嘿嘿嘿" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.parseInt(Integer.java:615) at com.macro.mall.portal.component.CancelOrderReceiver.handler(CancelOrderReceiver.java:31) at sun.reflect.GeneratedMethodAccessor122.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:50) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:196) ... 12 common frames omitted 複製代碼
看個人代碼:component
@RabbitHandler @RabbitListener(queues = "mall.order.cancel") public void handler(Long orderId){ Integer.parseInt("嘿嘿嘿"); // 演示異常使用 try { log.info("process orderId:{}", orderId); portalOrderService.cancelOrder(orderId); } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); // 異常處理 cancelOrderSender.sendFailedMessage(orderId); } } 複製代碼
很明顯Integer.parseInt("嘿嘿嘿")
會報錯,致使異常刷屏orm
將監聽方法內的全部代碼用try...cache
包裹,並在cache
中增長異常處理,以下代碼:
@RabbitHandler @RabbitListener(queues = "mall.order.cancel") public void handler(Long orderId){ try { Integer.parseInt("嘿嘿嘿"); // 演示異常使用 log.info("process orderId:{}", orderId); portalOrderService.cancelOrder(orderId); } catch (Exception e) { log.error(ExceptionUtils.getStackTrace(e)); // 異常處理 cancelOrderSender.sendFailedMessage(orderId); } } 複製代碼
先寫這麼多吧,後續遇到問題會繼續更新,若是有好的方案歡迎給我留言,共同窗習共同進步