天天滚动:抓到Dubbo异步调用的小BUG再送你一个贡献开源代码的机会

2022-07-03 02:43:44

  他说遭遇了一个Dubbo异步挪用的题目,狐疑是个BUG,提到BUG我可就不困了,说未必能够水,哦不...写一篇作品。

  本日创造一个题目 有一个dubbo接口返回类型是boolean, 把接口从同步改成异步 server 端返回true 消费端却返回false,把boolean改成Boolean就能寻常返回结果 有际遇过这个题目吗

  但这个是生意编码典型,借使RPC框架不行操纵boolean动作返回值,岂不是个BUG?并且他夸大了是同步改为异步挪用才映现这种境况,诠释同步没题目,有恐怕是异步挪用的锅。

  于是我顺口问了Dubbo的版本,说未必是某个版本的BUG。获得复兴,是2.7.4版本的Dubbo。

  先料想一下是哪里的题目,server端返回true,该当题目不大,恐怕是client端哪里转换犯错了。但这都是猜思,咱们直接从client端吸收到的数据入手,借使吸收的数据没题目,必定便是后续执掌出了点小舛讹。

  借使你不谙习,那就对照艰苦了,推举读一下之前的作品《我是一个Dubbo数据包...》,领会得越众,干活就越速。

  遵照咱们的思法,奉行挨次该当是①、③、②,然则这里很怪异,并没有遵照咱们的预期奉行,而是先奉行①,再奉行②,终末奉行③!

  看到这里忖度有一面小伙伴创造了题目,寻常境况下,Dubbo的异步挪用,奉行挪用后,不会立马获得结果,只会拿到一个null或者一个CompletableFuture,然后正在回调手法中守候server端的返回。

  咱们先看为什么会返回false。这里的callable是Dubbo天生的一个代办类,原来便是封装了挪用Provider的逻辑,有没有举措看看他封装的逻辑呢?有!用arthas。

  attach到咱们的Consumer过程上,奉行sc敕令(查看已加载的类)查看一齐天生的代办类,因为咱们的Demo就天生了一个,是以看起来很明确

  看到这里忖度小伙伴们又揭开了一层怀疑,oke便是去挪用Provider,因为这里是异步挪用,肯定返回的是null,是以返回值界说为boolean的手法返回了false。

  看到这里,忖度小伙伴们对《Java拓荒手册》里的典型有了更深的解析,这里的执掌成false也是无奈之举,否则岂非返回true?属于音讯遗失了,无法辨别是挪用的返回仍是其他特殊境况。

  圈出来的这段代码令人深思,越发是终末一行,为啥直接将CompletableFuture设立为达成?

  起初这个评释的格局上下纷歧,//之后讲意思是需求一个空格的,我感觉这里提个PR改下代码格局必定能被担当~

  其次local invoke,我解析该当是injvm这种挪用,为啥要格外执掌?这个执掌直接就导致了返回根基类型的接口正在异步挪用时肯定会返回false的BUG。

  咱们测试一下injvm的挪用,将demo中injvm参数改为true,Consumer和Provider都正在一个过程中,果真和评释说的相通:

  我感觉这该当算是Dubbo的一个BUG,固然这种写法不筑议,但动作一款RPC框架,这个毛病仍是不该当。

  修复的举措便是正在injvm分支这里加上判定,借使是injvm挪用仍是连结近况,借使不是injvm挪用,直接漠视,走终末的return逻辑:

  排查流程中还查找了github,但没有什么创造,诠释这个BUG遭遇的人很少,恐怕是专家用异步挪用正本就很少,再加上返回根基类型就更少,是以也不怪异。

  可是话说回来,咱们写代码最好仍是要恪守典型,这些都是古人工咱们总结的最佳实施,借使不按典型来,恐怕就会蓄意思不到的题目。

  终末,感激群里小伙伴供应素材,感激专家的阅读,借使能动动小手助我点个赞和正在看就更好了。咱们下期再睹~