RocketMQ异常处理

来源:9-22 Spring Cloud Stream异常处理

MkCorden

2020-05-07

版本:

  • Spring Cloud Version:Hoxton.SR3
  • Spring Cloud Alibaba Version:2.2.0.RELEASE
  • RocketMQ Version:4.4.0

生产端

使用Spring Cloud Stream发送普通消息

mySource.output().send(MessageBuilder.withPayload(userDTO).build());

消费端

 @StreamListener(MySink.MY_SINK)
    public void consumerMessage2(String messageBody){
        log.info("-----接收到消息体MySink-----{}",messageBody);
        throw new RuntimeException("error happen >>>>>");
    }

局部异常处理

@ServiceActivator(inputChannel = "error-stream.test-error-stream.errors")
    public void handleError(ErrorMessage message) {
        Throwable throwable = message.getPayload();
        log.error("---------------截获异常{}", throwable.getMessage());
        Message<?> originalMessage = message.getOriginalMessage();
        assert originalMessage != null;
        log.info("---------------原始消息体 = {}", new String((byte[]) originalMessage.getPayload()));
    }

问题

局部异常捕获到了,message.getOriginalMessage()获取为空,如何获取原始消息体?

写回答

2回答

大目

2020-08-05

不好意思,后来忘了……

先说解决方案:

//img.mukewang.com/szimg/5f2aaf0a097bc5f228641798.jpg

添加如图的配置即可解决。也就是说,关闭掉spring cloud stream默认的重试即可。

======

下面聊下我定位问题的过程:

在没有添加上述配置的情况下:

首先,我通过打断点的方式,发现ErrorMessage是在

org.springframework.integration.support.DefaultErrorMessageStrategy#buildErrorMessage构建的,代码如下:

//img1.sycdn.imooc.com/szimg/5f2aafae09c5086a27780712.jpg

如图,inputMessage是个null,于是进入了else分支。于是不会拿到getOriginalMessage。


而,这个方法是在:

//img.mukewang.com/szimg/5f2ab064091285c328140666.jpg

调用的,它管AttributeAccessor叫context。于是,我心想,会不会是因为重试导致的上下文数据丢失呢?

于是我就添加了上面那行配置,然后就解决了。

====

定位问题的过程有猜的成分在里面。

个人怀疑,这可能是Spring Cloud Alibaba Stream实现的一个小坑,重试和错误处理不能同时使用。

不过暂时没有去深究。


希望对你有所帮助。

0
1
MkCorden
非常感谢!
2021-01-13
共1条回复

大目

2020-05-08

帮忙提供下您的代码 & 操作步骤,我来看看哦。

0
3
MkCorden
回复
大目
老师……
2020-08-05
共3条回复

Spring Cloud Alibaba微服务从入门到进阶

面向未来微服务:熟练掌握Spring Cloud Alibaba

3085 学习 · 1324 问题

查看课程