【问题经验】dubbo回声测试异常(NumberFormatException:null)

现象

     在用dubbo回声测试机制做回声测试时返回异常信息"NumberFormatException:null"

cause: org.apache.dubbo.remoting.RemotingException: java.util.concurrent.CompletionException: java.lang.NumberFormatException: null java.util.concurrent.CompletionException: java.lang.NumberFormatException: null at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292) 

分析

     异常是RemotingException说明不是消费者端抛的,大概率是提供者端抛的异常。因为在测试环境必现,所以直接用debug调试跟踪了一下代码,发现抛异常的地方是在org.apache.dubbo.monitor.support.MonitorFilter.MonitorListener#onResponse位置

断点位置invocation.getAttachment(MONITOR_FILTER_START_TIME)返回值是null。

     再跟一下源码发现org.apache.dubbo.monitor.support.MonitorFilter#invoke里对MONITOR_FILTER_START_TIME赋值

    停下来思考下,回声测试这个地方为啥没有设置值?我们知道回声测试是利用EchoFilter来实现,EchoFilter发现请求对方法名是"$echo"就直接返回接口并且终止Dubbo的Invoker链(即后面的Filter以及真正的服务方法都不会执行到)。很巧,EchoFilter优先级比MonitorFilter优先级高,也就是回声测试MonitorFilter没有执行到,也就没用给invocation设置"MONITOR_FILTER_START_TIME"。 但是在invoke完成后会再次遍历所有的Filter,如果是ListenableFilter则执行org.apache.dubbo.rpc.Filter.Listener#onResponse。MonitorFilter也继承了ListenableFilter从而中招。

【问题经验】dubbo回声测试异常(NumberFormatException:null)_第1张图片

方案

    最好是dubbo源码修改一下。再不修改源码的情况下,可用以下两种方式规避:

    1 去除monitor参数

     笔者查看源码发现只有URL中带了monitor参数才会执行到抛异常的地方,所以只要我们关闭monitor特性即可。

    2 重写MonitorFilter

  • 自定义CustomMonitorFilter继承MonitorFilter,在抛异常的位置加一个判断
  • 配置Dubbo SPI加载customMonitor=xx.xx.xx.CustomMonitorFilter
  • 在dubbo:provider的配置上加上"filter=-monitor,customMonitor"(提供者去除默认的MonitorFilter,加上自定义的CustomMonitorFilter)

引申思考

     再思考下Dubbo这样实现的合理性,"只有被执行了Filter,它的listener才被执行" 这样是不是更合理

你可能感兴趣的:(问题经验,web开发)