1.Java教程:dubbo源码解析-网络通信
2.我找到了Dubbo源码的源码BUG,同事纷纷说我有点东西
3.Dubbo源码解析:网络通信
4.dubboè¿ä¹å®ç°ç°åº¦å°±å¯¹äº
Java教程:dubbo源码解析-网络通信
在之前的源码内容中,我们探讨了消费者端服务发现与提供者端服务暴露的源码相关内容,同时了解到消费者端通过内置的源码负载均衡算法获取合适的调用invoker进行远程调用。接下来,源码我们聚焦于远程调用过程,源码网页填表源码即网络通信的源码细节。
网络通信位于Remoting模块中,源码支持多种通信协议,源码包括但不限于:dubbo协议、源码rmi协议、源码hessian协议、源码ty进行网络通讯,源码NettyClient.doOpen()方法中可以看到Netty的源码相关类。序列化接口包括但不限于:Serialization接口、源码Hessian2Serialization接口、Kryo接口、FST接口等。
序列化方式如Kryo和FST,性能往往优于hessian2,能够显著提高序列化性能。这些高效Java序列化方式的单机魔兽源码引入,可以优化Dubbo的序列化过程。
在配置Dubbo RPC时,引入Kryo和FST非常简单,只需在RPC的XML配置中添加相应的属性即可。
关于服务消费方发送请求,Dubbo框架定义了私有的RPC协议,消息头和消息体分别用于存储元信息和具体调用消息。消息头包括魔数、数据包类型、消息体长度等。消息体包含调用消息,如方法名称、参数列表等。请求编码和解码过程涉及编解码器的使用,编码过程包括消息头的写入、序列化数据的存储以及长度的写入。解码过程则涉及消息头的读取、序列化数据的解析以及调用方法名、参数等信息的提取。
提供方接收请求后,服务调用过程包含请求解码、appui页面源码调用服务以及返回结果。解码过程在NettyHandler中完成,通过ChannelEventRunnable和DecodeHandler进一步处理请求。服务调用完成后,通过Invoker的invoke方法调用服务逻辑。响应数据的编码与请求数据编码过程类似,涉及数据包的构造与发送。
服务消费方接收调用结果后,首先进行响应数据解码,获得Response对象,并传递给下一个处理器NettyHandler。处理后,响应数据被派发到线程池中,此过程与服务提供方接收请求的过程类似。
在异步通信场景中,Dubbo在通信层面为异步操作,通信线程不会等待结果返回。默认情况下,RPC调用被视为同步操作。Dubbo通过CompletableFuture实现了异步转同步操作,通过设置异步返回结果并使用CompletableFuture的绘图库源码get()方法等待完成。
对于异步多线程数据一致性问题,Dubbo使用编号将响应对象与Future对象关联,确保每个响应对象被正确传递到相应的Future对象。通过在创建Future时传入Request对象,可以获取调用编号并建立映射关系。线程池中的线程根据Response对象中的调用编号找到对应的Future对象,将响应结果设置到Future对象中,供用户线程获取。
为了检测Client端与Server端的连通性,Dubbo采用双向心跳机制。HeaderExchangeClient初始化时,开启两个定时任务:发送心跳请求和处理重连与断连。心跳检测定时任务HeartbeatTimerTask确保连接空闲时向对端发送心跳包,而ReconnectTimerTask则负责检测连接状态,当判定为超时后,客户端选择重连,服务端采取断开连接的措施。
我找到了Dubbo源码的BUG,同事纷纷说我有点东西
某天,运营反馈称,执行一次保存操作后,网上开源码后台出现3条数据,我立刻怀疑可能存在代码问题。为了确保不会误判,我要求暂停操作,保留现场,以便我进行排查。
查看新增代码,发现是同事三歪进行的改动,他将原有的dubbo XML配置方式改为了注解方式。我询问其改动详情,得知他是更改了模块的配置方式。于是,我决定深入研究,找出问题所在。
dubbo配置方式多样,最常见的为XML配置与注解配置。我已初步推测原因,接下来将进行详细的调试过程。
我使用dubbo版本2.6.2进行调试。首先,针对采用@Reference注解条件下的重试次数配置,我发现调用接口时,会跳转到InvokerInvocationHandler的invoke方法。继续跟踪,最终定位到FailoverClusterInvoker的doInvoke方法。在该方法中,我关注到获取配置的retries值,发现其默认值为null,导致最终计算出的重试次数为3。
采用dubbo:reference标签配置重试次数时,同样在获取属性值后,发现其默认值为0,与注解配置一致,最终计算出的重试次数为1。对比两种配置方式,我总结了以下原因:
在@Reference注解形式下,dubbo会在注入代理对象时,通过自定义驱动器ReferenceAnnotationBeanPostProcessor来注入属性。在标签形式下,虽然也使用了Autowired注解,但dubbo会使用自定义名称空间解析器DubboNamespaceHandler进行解析。
在注解形式下,当配置retries为0时,属性值在注入过程中并未被解析为null,但进入buildReferenceBean时,因nullSafeEquals方法的处理,导致默认值和实际值不一致,最终未保存到map中。而标签形式下,解析器能够正确解析出retries的值为0,避免了后续的问题。
总结发现,采用@Reference注解配置重试次数时,dubbo在注入属性过程中存在逻辑处理上的问题,导致默认值与实际值不一致。此为dubbo的一个逻辑bug。建议在不需要重试时,设置retries为-1,以确保接口的幂等性。需要重试时,设置为1或更大值。
问题解决后,我优化了文件操作,将其改为异步处理,从而缩短了主流程的时间。最终,数据出现3条的状况得以解决。
此问题已得到解决,并在后续dubbo版本2.7.3中修复,确保了在注解配置方式下,nullSafeEquals方法能够正确处理默认值与实际值一致的情况。
Dubbo源码解析:网络通信
<dubbo源码解析:深入理解网络通信
在之前的章节中,我们已经了解了消费者如何通过服务发现和负载均衡机制找到提供者并进行远程调用。本章将重点解析网络通信的实现细节。
网络通信主要在Dubbo的Remoting模块中进行,涉及多种通信协议,包括dubbo协议、RMI、Hessian、HTTP、WebService、Thrift、REST、gRPC、Memcached和Redis等。每个协议都有其特定的优缺点,如Dubbo协议适用于高并发场景,而RMI则使用标准JDK序列化。
Dubbo的序列化机制支持多种方式,如Hessian2、Kryo、FST等。近年来,高效序列化技术如Kryo和FST的出现,可提升性能,只需在配置中简单添加即可优化。
关于数据格式和粘包拆包问题,Dubbo采用私有RPC协议,消息头存储元信息,如魔法数和数据类型,消息体则包含调用信息。消费者发送请求时,会通过MockClusterInvoker封装服务降级逻辑,然后通过序列化转换为网络可传输的数据格式。
服务提供方接收请求时,首先对数据包进行解码,确认其格式正确性,然后调用服务逻辑。提供方返回调用结果时,同样经过序列化和编码,最后通过NettyChannel发送给消费者。
在心跳检测方面,Dubbo采用双向心跳机制,客户端和服务端定期发送心跳请求以维持连接。此外,还通过定时任务处理重连和断连,确保连接的稳定性和可靠性。
总的来说,Dubbo的网络通信模块精细且灵活,通过多种协议和优化技术确保服务调用的高效和可靠性。
dubboè¿ä¹å®ç°ç°åº¦å°±å¯¹äº
èæ¯
为äºä¿è¯çº¿ä¸ä¸å¡è´¨éï¼éè¦ä¸å¥åå°ç°åº¦ç³»ç»ãç®æ æ¯éè¿ç®æçé ç½®å³å¯å°ç³»ç»ä¸é¨åçç¨æ·è¿è¡ç°åº¦
éè¦æ¯æçåè½ç¹
Api => Service A => Service B => Service C => Service D
web-apiææ¶ä¸å å ¥ç°åº¦ï¼å¦æå å ¥ç°åº¦ä¾èµäºç½å ³æ¥å ¥
å¦ä½å®ç°ï¼
ç°åº¦ç¯å¢(gray_evn)ï¼
ç°åº¦ç¨æ·è¡¨(gray_user)
ç°åº¦åºç¨è¡¨(gray_application)
ç°åº¦çæå¡è¡¨(gray_service)
åä¸ä¸ªç°åº¦çæå¡åªè½åºç°å¨ä¸ä¸ªç°åº¦çç¯å¢é
å¨åºç¨å¯å¨æ¶ï¼æ ¹æ®è¯¥åºç¨æå¨ç°åº¦ç¯å¢æºå¨å表ï¼å¤æ该åºç¨å¨è¿ä¸ªå°æºå¨æ¯å¦éè¦ç°åº¦ï¼å¦ææ¯ï¼åæ ¹æ®ç°åº¦çæå¡è¡¨é ç½®æå¡çç°åº¦é ç½®ï¼è¯¥æå¡è®¾ç½®ä¸ºç°åº¦groupï¼ã éè¿ä½¿ç¨eanPostProcessoræ¥å£æ¥å®æç°åº¦çåå§åä¹åï¼éè¿groupædubboæå¡è¢«ååç°åº¦ç¯å¢ãæ£å¼ç¯å¢ãè¿ééè¦æ³¨æçæ¯ï¼è¯¥ç°åº¦ç³»ç»çæ ¸å¿ä¹ä¸å°±æ¯éè¿groupè¿è¡ç°åº¦ç¯å¢çååã
å ·ä½æµç¨å¦å¾ï¼
å¨æçè·¯ç±
dubboæå¡è°ç¨ç顺åºï¼loadBalance -> filter
SpringMvc Intercepter:
1.è·åå½åç»å½ç¨æ·
2.æ¥è¯¢ç¨æ·æ¯å¦å¨åªäºç°åº¦ç¯å¢ä¸
3.æææç°åº¦ç¯å¢çgroupæ¾å ¥å°dubboçattachmentéé¢
GrayLoadBalance:
ç±äºæå¡å¯å¨æ¯é»è®¤æ¯å§æ¶è´¹ç«¯çgroup设置æäºâ*âï¼æ以å¨loadBalanceéé¢ä¼æ¿å°ææProvideræä¾çInvoker(å æ¬æ£å¼ç¯å¢åç°åº¦ç¯å¢)ï¼æææçInvokeréè¿URLä¸çgroupè¿è¡åç»ï¼å¨ååºattachmentä¸çgroups;
å¤æåºè¿æ¬¡è°ç¨æ¯èµ°ç°åº¦è¿æ¯æ£å¼ï¼å¦ææ¯ç°åº¦ï¼éè¦è®¾ç½®ä¸ä¸group为ç°åº¦ç¯å¢çï¼è¿å对åºçInvoker
GrayFilter:
æattachmentä¸çgroupçå¼ï¼å¦ææ¯â*â,é£ä¹è®¾ç½®ä¸ºç©º