dubbo接口调用扔出RuntimeException

本文探讨了在Dubbo微服务中,当provider抛出自定义非受检异常时,consumer如何接收到Runtime异常的问题。分析了Dubbo的异常处理机制,指出如果consumer无法识别异常,Dubbo会将其包装为RuntimeException。总结了Dubbo处理异常的几种情况,并强调了开发者在异常处理上的责任。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景

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

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 那可就太冤枉它了!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值