写点什么

Dubbo Triple 异常处理

  • 2023-03-21
    广东
  • 本文字数:1654 字

    阅读完需:约 5 分钟

Dubbo Triple 异常处理

从 dubbo 协议切换到 triple 最大的不适应就是异常的处理,异常都成 RuntimeException。

社区有两种方向

  • 上下文透传错误码:采用 attachment 透传错误码和错误消息,相当于利用 http2 response header(不是 trailer)

  • 响应体中定义错误码

个人意见

针对内网微服务,错误码一定要在协议里面体现,这样才方便做错误码监控。

官网讨论贴

issues-10353issues-8363Triple协议异常设计

实现原理

通过定义 provider 和 consumer 的异常filter来无感处理。


注:用户自定义 filter 默认在内置 filter 之后


provider filter



@Activate(group = {CommonConstants.PROVIDER})public class TripleProviderExceptionFilter implements Filter, Filter.Listener {
@Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { return invoker.invoke(invocation); }
@Override public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) { if (!appResponse.hasException()) { return; } Throwable exception = appResponse.getException(); if (exception instanceof RpcException) { RpcException rpcException = (RpcException) exception; appResponse.setAttachment("err-code", rpcException.getCode()); appResponse.setAttachment("err-msg", rpcException.getMessage()); } else { appResponse.setAttachment("err-code", RpcException.UNKNOWN_EXCEPTION); appResponse.setAttachment("err-msg", exception.getMessage()); } }
@Override
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) { }}
复制代码


consumer filter 这样到消费者转变成 RpcException。



@Activate(group = {CommonConstants.CONSUMER})public class TripleConsumerExceptionFilter implements Filter, Filter.Listener {
@Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { return invoker.invoke(invocation); }
@Override public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) { if (!appResponse.hasException()) { return; } String code = appResponse.getAttachment("err-code"); String msg = appResponse.getAttachment("err-msg"); if (StringUtils.isNotEmpty(code)) { appResponse.setException(new RpcException(Integer.parseInt(code), msg)); } }
@Override public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
}}
复制代码


添加扩展申明


src |-main    |-resources        |-META-INF            |-dubbo                |-org.apache.dubbo.rpc.Filter
复制代码


org.apache.dubbo.rpc.Filter 中纯文本内容


tripleProviderException=com.seezoon.dubbo.support.filter.TripleProviderExceptionFiltertripleConsumerException=com.seezoon.dubbo.support.filter.TripleConsumerExceptionFilter
复制代码

扩展知识

如何做到全局异常处理呢,比如我们 provider 业务逻辑有参数验证错误,Sql 错误等。如果能像 spring 提供的@ContollerAdivce一样处理就方便了。


这里需要我们自定义类似异常 Advice 的功能,让所有错误都能变成 RpcException 携带我们错误码及错误信息。



@DubboAdvicepublic class DubboExceptionAdvice {
@DubboExceptionHandler({IllegalArgumentException.class}) public void illegalArgumentException(Exception e) { throw new RpcException(100, e.getMessage()); }}
复制代码


这块实现比较复杂,这块我们封装到我们企业级脚手架中,有兴趣的可以参考github


用户头像

路遥知马力. 2017-10-18 加入

曾就职平安、腾讯等公司。

评论

发布
暂无评论
Dubbo Triple 异常处理_dubbo_昵称不能为null_InfoQ写作社区