深度解析dubbo服务invoke响应处理流程(调用者端)

时间:2024-04-03 09:52:02

注:本文基于dubbo v2.6.1
在上篇《深度解析dubbo服务调用invoke流程(调用者端)》我们介绍了调用者端从代理类到netty发送消息整个invoke流程(下图 黄色箭头部分)。那么本篇将介绍服务提供者端响应回来结果我们调用端是怎么处理的,也就是下图红色箭头的部分
深度解析dubbo服务invoke响应处理流程(调用者端)
本文不会讲太细节的东西,只是过下整个流程。
深度解析dubbo服务invoke响应处理流程(调用者端)
在上文中我们讲过,NettyClient往netty的pipe中添加了三个handler,我们说过in的时候netty的handler是顺序执行的。在这里也就是先decoder ,接着是nettyClientHandler,本篇也就分为decode与NettyClientHandler来讲解

1.decode

当channel来信息的时候,先经过decode进行解码,根据dubbo 协议头(16字节)里面的length 获取data,然后将data解码成对象。我们可以简单看下adapter.getDecoder()获取到的InternalDecoder对象的decode方法。
深度解析dubbo服务invoke响应处理流程(调用者端)
其中里面codec.decode(channel,message);就涉及到我们的dubbo里面序列化与反序列化这一层了(最下面那层),这里我们就不展开介绍了(后面会有文章专门讲解dubbo协议),这里我画了一个大体的调用图。
深度解析dubbo服务invoke响应处理流程(调用者端)
这里我们只需要有个大体的认识就可以了,通过decode将buffer中的字节解码成了对象。

2.NettyClientHandler

这里这个handler其实是代表的handlers, 因为我们在上篇文章invoke调用的时候,可以发现一个requestHandler被包装了若干层,我们可以再来回顾下那个netty将消息发送出去,然后调用handler的sent方法的图
深度解析dubbo服务invoke响应处理流程(调用者端)
我们可以看到这个requestHandler被包装了这么多层。其实我们这里接收消息也差不多,只不过不是调用sent方法了,而是recevied方法。我们可以看下我画的这个handlers处理recevied的一个图
深度解析dubbo服务invoke响应处理流程(调用者端)
可以看到与上面那张图差不多,这里我对每个handler都做了什么事做了一下总结(这里的总结只是对响应的处理,其他处理还需要自己犯翻下源码),这里还是有2个注意的handler我们需要看下
一个是AllChannelHandler,我们可以看下这个它的received源码
深度解析dubbo服务invoke响应处理流程(调用者端)
这里是现获取线程池,然后使用线程池来处理这个事件。
出现了异常,如果message是request,然后是个线程池拒绝异常,这时候快速回复一个失败的响应。
我们来看下这个ChannelEventRunnable ,看看run方法是怎样处理这些事件的。
深度解析dubbo服务invoke响应处理流程(调用者端)
我们可以看到,不同的事件交给handler的不同方法来执行。
另一个是HeaderExchangeHandler,我们看下它的received源码
深度解析dubbo服务invoke响应处理流程(调用者端)
可以看出来,使用message的类型来处理,我们这里就看下这个message是response类型的时候那个handleResponse方法。
深度解析dubbo服务invoke响应处理流程(调用者端)
接着看下这个Future的received方法。
深度解析dubbo服务invoke响应处理流程(调用者端)
这里其实就是找到请求那时候的那个future,这里response.getId()获得的id其实就是当初request那个id。
如果future能在缓存中找到,就调用future对象的doReceived方法。找不到的话,就是超时了,然后被清理了。
我们接着在看future.doReceived(response)方法
深度解析dubbo服务invoke响应处理流程(调用者端)
这里主要是DubboInvoker.invoke方法发送出去请求后,然后返回一个Future,这个future就是当时发送的时候封装的那个。
然后不是异步调用的话就会等着返回结果
深度解析dubbo服务invoke响应处理流程(调用者端)
这个get方法获取的就是这个response的值。