apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.52k stars 26.43k forks source link

[3.0] AbstractDirectory存在NPE以及connectivityCheckFuture重新赋值的问题 #9210

Closed zrlw closed 3 years ago

zrlw commented 3 years ago

Environment

此外,上面异常日志信息暴露出MultiInstanceTest存在的问题: provider启动完成并不意味着reference端收到了注册中心的服务实例通知,此时客户端直接调用会因找不到服务注册信息而失败。

zrlw commented 3 years ago

派生类和AbstractDirectory一起对AbstractDirectory的成员invokers,validInvokers进行操作违反了开闭原则,代码散落在各个类里面也不利于维护。

zrlw commented 3 years ago

再说一下this.connectivityCheckFuture被创建的新任务重新赋值的问题: checkConnectivity异步创建的任务在结束前判断是否有新task,如果有就再次调用checkConnectivity:

  1. this.connectivityCheckFuture在checkConnectivity方法返回调用者之后又被赋了新值,但调用者并不知情;
  2. 调用者在旧的connectivityCheckFuture上等待的结果就是新task未执行完,调用者就继续执行后面的代码,然后出问题,比如: https://github.com/apache/dubbo/runs/4130565263?check_suite_focus=true
    2021-11-07T11:46:56.1815610Z [ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.19 s <<< FAILURE! - in org.apache.dubbo.rpc.cluster.support.ConnectivityValidationTest
    2021-11-07T11:46:56.1818867Z [ERROR] org.apache.dubbo.rpc.cluster.support.ConnectivityValidationTest.testRetry  Time elapsed: 0.007 s  <<< FAILURE!
    2021-11-07T11:46:56.1820680Z org.opentest4j.AssertionFailedError: expected: <2> but was: <1>
    2021-11-07T11:46:56.1822662Z    at org.apache.dubbo.rpc.cluster.support.ConnectivityValidationTest.testRetry(ConnectivityValidationTest.java:190)

    更新: 还不能简单地在checkConnectivity创建的task里面等待新任务结束,那样就违背了checkConnectivity的设计初衷,为了避免长时间占用connectivityExecutor,checkConnectivity采用的是分批处理的策略,所以PR #9211 最终没有修改checkConnectivity方法,而是修改了ConnectivityValidationTest的waitRefresh方法,将等待条件改为invokersToReconnect列表里没有需要进行recover的invoker。