RabbitMQ 排查无限循环故障

一 问题概述

出现无限循环异常日志: org.springframework.amqp.AmqpException: No method found for class [B

二 定位问题

首先查看消费者的监听方法中的参数是否与服务者的消息数据类型为一致。

例如:
消费者监听方法中参数类型为:String

    @RabbitHandler
    @RabbitListener(queues = CommonConstant.MEMBER_INFO_QUEUE)
    public void onMessage(String message){
        //业务代码...
    }
复制代码

服务者发送的消息类型为:byte[]

    @Autowired
    private RabbitTemplate template;
    
    public void send(){
        String json = "{}";
        template.convertAndSend(this.exchange, this.routingKey, json.getBytes(),null);
    }
复制代码

那么将会抛出上述所讲到的异常!!!,关键就是怕有人手贱要 .getBytes() 这样就导致消费者无法通过 String 类型去接收了(这就是问题所在!!),可以通过源码观察到RabbitMQ会根据传入参数类型设置不同的Content-type

    protected Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
        byte[] bytes = null;
        if (object instanceof byte[]) {
            bytes = (byte[])((byte[])object);
            //设置content-type
            messageProperties.setContentType("application/octet-stream");
        } else if (object instanceof String) {
            try {
                bytes = ((String)object).getBytes(this.defaultCharset);
            } catch (UnsupportedEncodingException var6) {
                throw new MessageConversionException("failed to convert to Message content", var6);
            }
            //设置content-type
            messageProperties.setContentType("text/plain");
            messageProperties.setContentEncoding(this.defaultCharset);
        } else if (object instanceof Serializable) {
            try {
                bytes = SerializationUtils.serialize(object);
            } catch (IllegalArgumentException var5) {
                throw new MessageConversionException("failed to convert to serialized Message content", var5);
            }
            //设置content-type
            messageProperties.setContentType("application/x-java-serialized-object");
        }

        if (bytes != null) {
            messageProperties.setContentLength((long)bytes.length);
            return new Message(bytes, messageProperties);
        } else {
            throw new IllegalArgumentException(this.getClass().getSimpleName() + " only supports String, byte[] and Serializable payloads, received: " + object.getClass().getName());
        }
    }
复制代码

三 解决

将服务者或消费者的参数类型更改为一致即可。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享