我找到了Dubbo源码的BUG,同事说我有点东西


点赞再看,养成习惯,微信搜索【三太子敖丙】关注这个互联网苟且偷生的工具人。

本文 GitHub github.com/JavaFamily 已录入,有一线大厂面试完整考点、材料以及我的系列文章。

布景

某天运营反馈,点了一次保存,可是后台呈现_ j q S ^ g w了3b j C D r ^ f I 条数据,我其时就想,不应该啊,这代码我几万年没动了,我其时就叫他先别操作了,保留一下现场,我去排查一下。

我看了下新增的代码,直接右键查看作者

我找到了Dubbo源码的BUG,同事说我有点东西

没想到三歪做过改动,我就去问三歪,XX模块的新增代码你是不是动过4 & & 0 z !

他沉默了很久没说话,然后抓起桌子上用剩下来的纸擦了擦鬓角留下的W I 3 e b 8 v汗水,咽了一下口水说,是的_ o j我改过,我把之前dubbo的xml装备办法改成了注解的办法。

怎么了?现在出BUG了?

你呀你,下次这种改& Z i z G l动跟我说一下,我估计是dubbo源码的bug吧,不要慌,让我去看看什么问题。

正文

其实dubboC _ ^ # ; ! j装备的办法有很多种,大家用的$ + Z u最多的便是xml装备的办法,假如不需求重试次数,我们会加上重试次数为0,因为他默许是有多次的。

<dubbo:referenceid="testServici m ue"interface="heiidea.trade.serc * ; c | Fvice.sdk.interfice.TestService"retries=k L D F /"0"/>

或许运用注解的办法

@Reference(retriew P Os=0)

其实我现已大概知道是Q – b v什么原因了,可是为了证明自己的猜想,于是敞开了接下来的debug之旅~~~

注:dubbo版别:2.6.2

首先是在选用@Refer9 / _ence注解条件下:

选用/ A 4 A@Reference注解装备重试次数

首先是都找到了dubbo重试的代码方位(启动dubbo项目,到调用接口时,F5进入办法,会跳转到InvokerInH ( xvocationH R ! 2 _andler中的iA y @ b 3nvQ | | [oke办法中,继续跟踪进入MockClusterInvX b ] Noker中的in_ ? f ( –voke办法,然后进入AbstractClusterInvoker中的invoke办法中,这里主要是拿到装备的负载均衡战略,后边会到FailoverCluste! n ] 8 zrInvoker的doInvoke办法中)。M – q ; [ ) M T

要点来了,这里会获取装备的retries值,能够看到上面装备的是0,可是取出来居然是null,如2 N : B 0 Y图:

我找到了Dubbo源码的BUG,同事说我有点东西
value为null

所以会回来defaultValue,加上自身调用的那一次,核算之后就会为3,如图:

我找到了Dubbo源码的BUG,同事说我有点东西
值为3

所以能够发现,选用@Reference注解的办法装备retries为0时,dubbo重试次数为2次(3中包括自身调用的那次)。

后边是选用 dubbo:reF K – * lference 标c p j 8 0 r ? k Y签的办法:

我找到了Dubbo源码的BUG,同事说我有点东西
dubbo标签办法

办法如上,在获取特点的时候i ; T g G,能够看到取得的值为0,和注解办法装备的一致,如图:

我找到了Dubbo源码的BUG,同事说我有点东西
value为0

加上自身调用的那一次,核算之后就会为1,如图:

我找到了Dubbo源码的BUG,同事说我有点东西
value为1

所以能够发现l 3 & 7 D ] Y – :,选用 dubbo:reference 标签办法装备retries为0时,dub) – l . + P 3bo重试次数为0(1为自身调用的那次)。

原因剖析

首先是@Referen0 D A m v j x o rce注解办法:

dubbo会把每个接口先解析为RC : / deferenceBean,加上RT R I s * . )eferenceBean完成了FactoryBean接口,所以在注入的时候,会调用getObject办法,生成署理目标。

可是这不是要害,因为到这一步时,一切的特点都现已加a Y D @载完成,所以需求找到dubbo解析注解中特点的代码方位。

dubbo会运用自定义驱动器R] ! CeferenceAnnotationBeanPostProcessor来注入特点,而具体履行注入的代码方位是在ReferenceAnnotationBeanPostProcessor类. R b Y p & 3 s的postProcessPropertyValues办法中调用inject办法履行的。

要点来了,因为选用标签时,是选用@Autowired注解注入,所以是选用sprih ; / R U Q ,ng原生办j j N x L x . F法注入,而在选用@Reference注解时,注入时会走到dubbo自己的ReferenceAnnotationBeanPostProcessor中私有内部类ReferenceFie5 D | OldElement的inj% [ ( , @ c {ect办法Z x { u x U 4中,然后调用buildReferenceBean创立ReferenceI m g w 1 L E %BH C B 7 &ean。

离原因越来越近了,在该办法中能够看到beanBuilder中的retries值仍是0,说明到这一步还6 P S 4没有被解析为null1 Y 9 S H,如图:

我找到了Dubbo源码的BUG,同事说我有点东西
retries为“0”

继续往下走,调用build办法中的+ _ mconfigureBean时,在2 9 5 M q q %第一步preConfigureBean中办法,在该办法中会创立AnnotationPropeZ L j a ~ W e N GrtyValuesAdaptQ I Z h Z = wer目标,在该目标构造办法中会调用adapt办法,然后走E i ,到AnnotationUtils中的getAttributes办法中,有N l d o [一个要害办法nullSafeEqualso R | e 6 z a ) ~,该办法会传入当时特点值和默许值。

假如相等,则会疏忽掉该特点– 0 K #,然后将契合l i h f O条件的特点放入actualAttributes这个map中,而我们的retries特点是0,和默许值一致,所以map中不会保存retries特点的值,只要timeout特点,因而呈现了后边获取的值为null。

注解办法debug告一段落。

我找到了Dubbo源码的BUG,同事说我有点东西
map不包括retries

后边是dubbo:reference标7 H # * o c { [签办法:

上面说到了,标签办法走到2 2 4 l 4inject时,会和注解办法有所不同,p + G % a ` H ?选用该标签时,dubbo会运用自d $ m ! a s定义的称号空间解析器去解析,很简单理解,spring也不知道它自定义标签里面那些玩意儿是什么Y 1 H [ ( E意思,所以dubbo会继承spring的。

Na5 S J lmespaceHandlerSupport,选用自定义的DubboNamespR q – H W Q % =aceHandler解析O G Y x F @ n T f器来g c m 4 e {解析的标签,如下图:

我找到了Dubbo源码的BUG,同事说我有点东西
dubbo自定义称号空间解析器

然后调用该类中的parse办法进行解析,而解析retries的地方便是获取class(此时的class便是上图绿色标明的Refel o 3 r 4 7 5renceBean的class,其父类中有G D } # F p很多很多set办法,其中5 j m就包括q y – e SsetRetrief U T ` h 4 Y | ps办法)中一切的办法,过滤出set开头的办法,然后切割出特点名,放入特点池中,能够看到此处解析出的值为0,并不为null,如下图:

我找到了Dubbo源码的BUG,同事说我有点东西
获取特点名的方{ @ C
我找到了Dubbo源码的BUG,同事说我有点东西
获取retries值为0

小结

画个简单图:

我找到了Dubbo源码的BUG,同事说我有点东西
大致流程x % ^ s a 7 * 0

结论

  • 选用注解办法:不装备r= v , p ` 4 p Tetries或许装备为0,都会重试两次,只要装备为 -1 或更小,才会不履行重试。

  • 选用标签办法:不装备retries会重试两次,装备为0或更小都不会重试。

所以主张大家} ! n x不需求重试时能够设置为-1,比如增删改操. E ; M d !作的接口,否则需求确保幂等性。( a O l I j需求重试则设置为1或更大,其实这应该算dubboY g 2 @ ; = O 3 .的一个dug吧?(我觉得是。。)

到这里就结束了,而上面说到的调用getObject办法便是后续服务发现以及和服务端树立长连接并回E . ( 3 $ +来署理目标了。

数据呈现3条是因为+ 8 | ^我定义了接口超时的时刻比较短,h $ q h可是我们的新增涉及文件的操作,流程时刻比较久,可是线程仍是在的,所以dubbop D e V 6 L u ;重试了三次,三次也都是c & 6 E O成功的了。

我后边把文件操作改成异步,然V M @ $ X 0后主流程是同步的时刻就缩短了很多。

弥补:2.7.3版别已修正N & ` * G 0 r + ,,便是在注解情况下,nullSaf4 _ +eEquals办法中的默许值和后边保持一致了,都是2,所以为0时也能保存到map中。

我是敖丙,一个在互联网苟且偷生的工具人。) U M f : A

你知道的越多,你不知道的越多C I _ q J $ J X F们的 1 D ) | h I 9三连】 便是丙丙创造的最大动力,我们下期见!

注:假如本篇博客有任何错误和主张,欢迎人才们留言,你快说句话啊


文章持续更新,能够微信搜索「 三太子敖丙 」第一时刻阅览,回复【材料】【I T ] V N】【简历】有我准备的一线大厂面试材料和简历模板,本文 Gih c z 1 ? q l ltHub github.com/JavaFamily 现已录入,有! s Y大厂面试完整考点,欢迎Star。

我找到了Dubbo源码的BUG,同事说我有点东西

发表评论

提供最优质的资源集合

立即查看 了解详情