dubbo接口调用扔出RuntimeException

一、背景

在日常业务开发过程中,我们为了让业务代码更健壮,遇到错误时返回的提示更友好,一般会自定义一些业务异常。根据业务需要,分为自定义受检异常和非受检异常

1.1 知识点回顾

Exception类及其子类,但不包括 RuntimeException 的子类,统称为受检异常。如果方法执行过程中有可能抛出此类异常,必须在方法签名上声明

RuntimeException 类及其子类,统称为非受检异常。如果方法执行过程中有可能抛出此类异常,可以不必在方法签名上声明

1.2 开发问题

开发中遇到一个问题:Dubbo RPC调用时,provider抛出的一个业务类非受检异常,consumer接到时却是RuntimeException 并且message被和堆栈信息拼接到了一起。

二、问题原理

Dubbo 微服务中,provider 分为apiserviceconsumer只需要引入 api 从注册中心调用service 实例即可。

service 中抛出一个自定义的非受检异常,且其相应api包中没有这个异常类时,就会出现异常被包装为RuntimeException的情况。

其实问题分析到这里,基本就有眉目了:Dubbo是一个RPC框架,客户端调用的都是远程方法,参数和返回值都是经过序列化和反序列化为字节数组传输的。consumer必须认识这个异常才能反序列化成功。

很明显,我们抛的这个异常 Dubbo认为consumer不认识,为了避免反序列化失败,从而对异常进行了包装。

下面结合源码阐述Dubbo的异常处理机制。

三、源码分析 

Dubbo 远程调用的异常由ExceptionFilter类处理

通过源码可以看到,该类的主要功能是返回接口抛出的异常,Dubbo将其定义为如下几种情况:

  1. 如果是checked异常,直接抛出
  2. 在方法签名上有声明,直接抛出
  3. 不符合1,2 的被认为是错误,会打印error日志,并尝试如下处理:
    • 异常类和接口类在同一个jar包里,直接抛出
    • JDK自带的异常,直接抛出
    • Dubbo本身的异常,直接抛出
    • 否则,包装成RuntimeException抛给客户端

事实上Dubbo作为RPC框架已经把各种抛异常的情况都考虑全了,最后如果Dubbo认为consumer不认识这个异常还会包装成RuntimeException兜底,防止反序列化失败。

如果发生了consumer找不到provider所抛异常的这种情况,不客气地讲,一定是开发者的问题,把这个归罪于Dubbo 那可就太冤枉它了!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值