修了Apache Dubbo的一个bug

沙海 2021年4月22日04:04:05Java评论40字数 4653阅读15分30秒阅读模式
摘要

速读摘要

速读摘要文章源自JAVA秀-https://www.javaxiu.com/19413.html

这个pr是修复LFU缓存策略在Dubbo中即使配置了,也不起作用的bug。经过上面的分析,其实你也发现了,这个并不是一个有什么技术含量的提交。当时这个版本推出之后,我就赶紧去研究了一下对应部分的源码,然后写下这篇自称为全网第一篇解析Dubbo 2.7.5里程碑版本中的客户端线程模型优化的文章。于是我就在想,我当时写文章的时候也是深入到源码里面了呀,为什么没有发现这样的问题呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

原文约 3251 | 图片 25 | 建议阅读 7 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug

大数据肌肉猿 文章源自JAVA秀-https://www.javaxiu.com/19413.html

以下文章来源于why技术,作者why技术文章源自JAVA秀-https://www.javaxiu.com/19413.html

文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

why技术文章源自JAVA秀-https://www.javaxiu.com/19413.html

一个主要写代码,经常写文章,偶尔拍视频的风骚程序猿。文章源自JAVA秀-https://www.javaxiu.com/19413.html

文章源自JAVA秀-https://www.javaxiu.com/19413.html

篇文章其实并没有什么技术性的分享,从我的角度而言,更多是记录和思考。文章源自JAVA秀-https://www.javaxiu.com/19413.html

把我对于源码和之前写的部分文章反哺给我的一些东西,带来的一点点思考分享给大家。文章源自JAVA秀-https://www.javaxiu.com/19413.html

一行源码

我很长时间没打开我的 Outlook 邮箱了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

前两天打开的时候发现我之前给 Dubbo 提交的 pr 居然已经被合并到 master 了:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

这是第一次,我提交的 pr 被合并了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这个 pr 是修复 LFU 缓存策略在 Dubbo 中即使配置了,也不起作用的 bug。文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是我也算是为开源项目贡献过源码的人了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

什么你问我贡献了多少代码?文章源自JAVA秀-https://www.javaxiu.com/19413.html

一行,是的,就一行!文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

而且,说起来,这次提交真的是没有什么技术含量的事情。因为这是一个必的 bug,只是很少有人用到这个功能而已。文章源自JAVA秀-https://www.javaxiu.com/19413.html

你知道的,当一个 bug 能稳定复现的时候,其实它已经就不算是一个 bug 了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是我想聊聊这次提交背后的一些东西。文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

发现与解决文章源自JAVA秀-https://www.javaxiu.com/19413.html

从宿命论的角度来说,当我写下面这篇文章的第一个字的时候,这个 bug 就注定是等着我去发现并修复了:文章源自JAVA秀-https://www.javaxiu.com/19413.html

其实吧,LRU也就那么回事。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而这篇文章我敲下第一个字的时间是 2020 年 12 月的下旬,这是我 2020 年的最后一篇技术原创文章。文章源自JAVA秀-https://www.javaxiu.com/19413.html

当我写 LRU 的时候,我就知道 LFU 肯定也是需要专门写一篇的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是 2021 年的第一篇技术原创文章,我就选题了 LFU。文章源自JAVA秀-https://www.javaxiu.com/19413.html

产生了这篇文章:文章源自JAVA秀-https://www.javaxiu.com/19413.html

哎,这让人抠脑壳的 LFU。文章源自JAVA秀-https://www.javaxiu.com/19413.html

写这篇文章的时候,我想起之前看 Dubbo 的版本,好像是提到了一下 LFU。文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是我翻到了 2.7.7 版本的发布内容:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

果然是支持了 LFU 缓存策略,于是翻出了提交的代码记录:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

虽然他的实现逻辑没有问题,Test 类也跑过去了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是毫不夸张的说,我看了一眼这个提交记录,通过眼神编译,就发现了这里势必是有问题的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

他仅仅是把 LFU 缓存策略集合到了 Dubbo 代码中,但是却未提供使用的入口。文章源自JAVA秀-https://www.javaxiu.com/19413.html

因为这里是基于 SPI 实现的,他没有在对应的配置文件中加入配置。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这个问题非常容易验证,我们可以看一下。文章源自JAVA秀-https://www.javaxiu.com/19413.html

其源码的位置是:org.apache.dubbo.common.utils.LFUCache文章源自JAVA秀-https://www.javaxiu.com/19413.html

源码里面告诉我这样配置一下就可以使用 LFU 的缓存策略:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是,当我这样配置,发起调用之后,是这样的:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

可以看到当前请求的缓存策略确实是 LFU。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是会抛出一个错误:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

No such extension org.apache.dubbo.cache.CacheFactory by name lfu文章源自JAVA秀-https://www.javaxiu.com/19413.html

没有 LFU 这个策略。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这不是玩我吗?文章源自JAVA秀-https://www.javaxiu.com/19413.html

再看一下具体的原因:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

org.apache.dubbo.common.extension.ExtensionLoader#getExtensionClasses 处只获取到了 4 个缓存策略,并没有我们想要的 LFU。文章源自JAVA秀-https://www.javaxiu.com/19413.html

所以,在这里抛出了异常:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

为什么没有找到我们想要的 LFU 呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

那就得看你熟不熟悉 SPI 了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

在 SPI 文件中,确实没有 LFU 的配置:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

所以,这是个 Bug,而这个 Bug 的解决方案,就是在 SPI 文件里面加上一行 LFU 的配置即可。文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

经过上面的分析,其实你也发现了,这个并不是一个有什么技术含量的提交。文章源自JAVA秀-https://www.javaxiu.com/19413.html

更多的是运气成分。文章源自JAVA秀-https://www.javaxiu.com/19413.html

只是由于对于 Dubbo 框架有些许的了解,所以对于这个地方,我发现问题、定位问题、解决问题的速度非常的快。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这是运气给不了我的东西。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这需要日复一日的潜入到框架中去,去感受它的脉络,梳理它的结构,学习它的思想。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这是需要时间去沉淀和学习的东西。文章源自JAVA秀-https://www.javaxiu.com/19413.html

注意,我说的是“潜入”,而非是流于表面的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

什么是流于表面的呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

比如,如果你之前没有用过 Dubbo 框架,但你又想去了解,学习它。文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是你看到了我的这篇或者其他的和 Dubbo 相关的文章,企图从这些文章中入手。文章源自JAVA秀-https://www.javaxiu.com/19413.html

记住鲁迅先生的话:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

这里只适合查漏补缺,不适合系统的学习。文章源自JAVA秀-https://www.javaxiu.com/19413.html

亦或者是你在搜索框里面,输入 “Dubbo”,然后漫无目的的看了起来。文章源自JAVA秀-https://www.javaxiu.com/19413.html

哪怕你买了一本 Dubbo 相关的书或者看了 Dubbo 相关的系列视频,进行系统的学习。文章源自JAVA秀-https://www.javaxiu.com/19413.html

我觉得,只要没有自己亲手去做,都属于流于表面。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而自己动手的第一步,就是搭建 Demo,从 Demo 入手。文章源自JAVA秀-https://www.javaxiu.com/19413.html

到后面高阶一点的就是你了解到了这个框架的前世今生,能在几个大版本之间进行横向对比,知道为什么升级、怎么升级、升级之后是怎么样的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

再之后,能细致到某一个大的模块的演变是怎样的,历史上出现过哪些 Bug,是怎么去修复的,在哪个版本之后修复了,是稳定的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

再举个例子吧。文章源自JAVA秀-https://www.javaxiu.com/19413.html

另外一个bug

回到最开始的地方,我为什么会在写 LFU 的时候联想到 Dubbo 呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

因为在 2.7.7 这个版本发布的时候,我就关注到了它。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而当时关注到它的原因并不是 LFU ,而是新增了一种负载均衡策略:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是我把之前的文章进行了汇总,写下了这篇文章:文章源自JAVA秀-https://www.javaxiu.com/19413.html

吐血输出:2万字长文带你细细盘点五种负载均衡策略。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而其中一致性哈希负载均衡策略,我在实践的时候也发现了一个 bug。文章源自JAVA秀-https://www.javaxiu.com/19413.html

其实这个 bug 也是一个必现的 bug,为什么没有被爆出来的原因,我想是因为当前的版本使用的人不多,而使用一致性哈希负载均衡策略的就更少了,甚至没有。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这个 bug 具体是这样的:文章源自JAVA秀-https://www.javaxiu.com/19413.html

https://github.com/apache/dubbo/issues/5429文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

我已经知道了在一致性哈希算法中的这行代码就是导致 bug 的原因:文章源自JAVA秀-https://www.javaxiu.com/19413.html

System.identityHashCode(invokers)文章源自JAVA秀-https://www.javaxiu.com/19413.html

甚至我也知道了,这行代码导致 bug 的原因是 invokers 这个集合的地址变了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这个集合里面,放的就是服务提供者列表。文章源自JAVA秀-https://www.javaxiu.com/19413.html

集合里面的服务者列表其实并没有变化,只是每次都用了一个新的 list 来装这些服务提供者。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而为什么每次都用一个新的 list 来装,我也找到了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

问题就出在 TagRouter 中:文章源自JAVA秀-https://www.javaxiu.com/19413.html

org.apache.dubbo.rpc.cluster.router.tag.TagRouter#filterInvoker文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

基本上到这里,也就明确原因了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是我前面说了,更高一级的是了解这个框架的前世今生。文章源自JAVA秀-https://www.javaxiu.com/19413.html

问题出在 TagRouter,那么这个 TagRouter 怎么来的呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

如果了解 Dubbo 2.7.x 版本新特性的朋友可能知道,标签路由是 Dubbo2.7 引入的新功能。文章源自JAVA秀-https://www.javaxiu.com/19413.html

巧就巧在我还真的清楚这个地方的来龙去脉。文章源自JAVA秀-https://www.javaxiu.com/19413.html

因为我的第一篇技术文章就是写的 Dubbo 2.7 新特性,当时进行了一个了解。文章源自JAVA秀-https://www.javaxiu.com/19413.html

没想到一年多以后,竟然还呼应上了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而这个 bug,其实也是一行代码就能修复;文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

而我当时为什么没有去修复呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

因为最开始找到这个 bug 的时候,我想到的解决方案是写个工具类。文章源自JAVA秀-https://www.javaxiu.com/19413.html

思路也是只关心 List 里面的元素,而不关心 List 这个容器,但是实现方式比较复杂,改动点较多,还需要写一个工具类。文章源自JAVA秀-https://www.javaxiu.com/19413.html

当时就没动手,想着先提个 issue 放着,有时间了再弄。文章源自JAVA秀-https://www.javaxiu.com/19413.html

结果,没想到 issue 放上去的当天就有人回复并了一个我没有想到的解决方案:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

看到这个回复的时候,我才一下回过神来,原来一行代码就能代替我写的工具类了啊。文章源自JAVA秀-https://www.javaxiu.com/19413.html

而对于其中涉及到的知识点,我是知道的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

我反思了一下自己为什么没有想到这个方案。文章源自JAVA秀-https://www.javaxiu.com/19413.html

其实就是对于已知道的知识点,掌握不够深刻导致的,没有达到融会贯通的地步。文章源自JAVA秀-https://www.javaxiu.com/19413.html

知其然,也知其所以然,可惜在需要使用的场景稍稍一变的情况下,就想不起来了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

知道知识点,但是该用的时候却记不起来,这种情况其实挺常见的,那怎么解决呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是我写下了这篇文章:文章源自JAVA秀-https://www.javaxiu.com/19413.html

够强!一行代码就修复了我提的Dubbo的Bug。文章源自JAVA秀-https://www.javaxiu.com/19413.html

这篇文章就是我的解决方案,记录下来嘛。文章源自JAVA秀-https://www.javaxiu.com/19413.html

就像高中的时候人手一本的错题本,做错的题,不会的题都抄下来嘛。没事的时候翻一翻,总有下次碰到的时候。再次碰到时,就是“一雪前耻”的机会。文章源自JAVA秀-https://www.javaxiu.com/19413.html

写过但没有发现的bug

我之前还写过一样的一篇文章:文章源自JAVA秀-https://www.javaxiu.com/19413.html

Dubbo 2.7.5在线程模型上的优化文章源自JAVA秀-https://www.javaxiu.com/19413.html

当时这个版本推出之后,我就赶紧去研究了一下对应部分的源码,然后写下这篇自称为全网第一篇解析 Dubbo 2.7.5 里程碑版本中的客户端线程模型优化的文章。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是前两天我看提交记录的时候,发现了这样的一个提交:文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

并找到了对应的 issue:文章源自JAVA秀-https://www.javaxiu.com/19413.html

https://github.com/apache/dubbo/issues/7054文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

根据这个 issue,我去看了一下对应的源码,确实是存在他描述的问题。文章源自JAVA秀-https://www.javaxiu.com/19413.html

于是我就在想,我当时写文章的时候也是深入到源码里面了呀,为什么没有发现这样的问题呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

我想原因还是在于自己当时思考的深度不够,仅仅是搭建了一个非常简陋的 Demo,而且把心思聚焦到了前后版本差异对比上。文章源自JAVA秀-https://www.javaxiu.com/19413.html

只是摸到了一个大概的样子,于是被源码牵着走了,并没有跳出源码的包围,带着质疑的眼光去审视它。文章源自JAVA秀-https://www.javaxiu.com/19413.html

所以,对于这种比较深层次的、一环扣一环的问题,自己还是流于表面了一些。文章源自JAVA秀-https://www.javaxiu.com/19413.html

一旦被源码牵着走了,大概率的情况下就会无条件的相信源码。毫无质疑之心。文章源自JAVA秀-https://www.javaxiu.com/19413.html

怎么看源码

前面举了三个例子,一个是发现并解决了 bug,一个是仅发现未解决的 bug,一个是有 bug 但没有发现。文章源自JAVA秀-https://www.javaxiu.com/19413.html

前两个 bug 都有一个共性,在简单的 Demo 下就是必现的,只要跑到了对应的地方,就会出现和预期不符的情况,比较容易发现。文章源自JAVA秀-https://www.javaxiu.com/19413.html

最后一个 bug 隐藏的比较深入一点,也许你触发了,但是程序自愈了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

当有一天我能发现并解决这样的 bug 时,我就不会说这是运气了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

但是发现这些 bug 的前提是得动手搭建 Demo 呀。文章源自JAVA秀-https://www.javaxiu.com/19413.html

你不看源码,只是看网上的文章,是永远发现不了问题的,也是潜入不进去的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

分享一下我看源码的方法吧。文章源自JAVA秀-https://www.javaxiu.com/19413.html

我们知道开源框架的设计和理念大多是非常优秀的,但是源码里面的细枝末节特别的多,一不小心就容易在源码里面迷失,直接就是一波劝退。文章源自JAVA秀-https://www.javaxiu.com/19413.html

所以,对于初读源码的同学,首先要做的就是把核心流程梳理出来,边梳理边画图,要多画图,别怕麻烦。文章源自JAVA秀-https://www.javaxiu.com/19413.html

对于几处关键的源码,一定要写上自己的备注。因为你知道的,当时也许你对这个地方为什么这样写门清,但是隔段时间再回来看,就摸不着头脑了。这个时候,备注就显得非常重要了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

对于看不明白的地方,打断点,疯狂的调试,反复的调试。文章源自JAVA秀-https://www.javaxiu.com/19413.html

等待主流程摸清楚之后,再去进入到源码的细节部分。文章源自JAVA秀-https://www.javaxiu.com/19413.html

举个简单的例子,比如你看 Dubbo 源码,先摸清楚它一次请求大概的调用链路之后,再去细致了解其中负载均衡的部分。文章源自JAVA秀-https://www.javaxiu.com/19413.html

然后,就是多复习,多巩固了。文章源自JAVA秀-https://www.javaxiu.com/19413.html

修了Apache Dubbo的一个bug文章源自JAVA秀-https://www.javaxiu.com/19413.html

你发现没有,我说的这些其实你也知道,或者其他人也是这样说的。文章源自JAVA秀-https://www.javaxiu.com/19413.html

为什么你看的时候就老是看不进去呢?不得要领呢?文章源自JAVA秀-https://www.javaxiu.com/19413.html

是的,我开始也是这样的。但是,无它,唯反复练习尔。文章源自JAVA秀-https://www.javaxiu.com/19413.html

共勉之。文章源自JAVA秀-https://www.javaxiu.com/19413.html

<span style="margin:0;padding:0;max-width:100% !important;-webkit-box-sizing:border-box !important;word-wrap:break-word !important;color:rgb(255,0,0);overflow-wrap:break-word !important;box-sizing:border-box !important"--<end--文章源自JAVA秀-https://www.javaxiu.com/19413.html

扫描下方二维码添加好友,备注【交流】可私聊交流,也可进资源丰富学习群更文不易,点个“在看”支持一下?
文章源自JAVA秀-https://www.javaxiu.com/19413.html

阅读原文文章源自JAVA秀-https://www.javaxiu.com/19413.html

继续阅读
速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
weinxin
资源分享QQ群
本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
  • 版权声明:本站是JAVA秀团队的技术分享社区,我们会经常分享资源和教程。
  • 转载请注明:修了Apache Dubbo的一个bug - JAVA秀 ☜(ˆ▽ˆ)
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定