Dubbo源码四:全网最细的Dubbo服务调用【消费端】

入口

image.png

MockClusterInvoker.invoke

image.png

AbstractClusterInvoker.invoke

image.png

list(invocation) ->RegistryDirectory.doList

这个list方法最终会调用到RegistryDirectory.doList
image.png

这个方法会调用routerChain.route

RouterChain.route

image.png

AbstractClusterInvoker.invoke

abstractClusterInvoker.invoke会最终执行到FailoverClusterInvoker.doInvoke

FailoverClusterInvoker.doInvoke

image.png
这里的invoker.invoke 会调用到InvokerWrapper.invoke(invocation)

InvokerWrapper.invoke

image.png
invoker.invoke最终会调用到 ProtocalFilterWrapper.invoke

ProtocalFilterWrapper.invoke

image.png
开始执行Filter链,执行完得到结果后,会获取ListenableFilter中的listener,执行listener的onResponse方法

ConsumerContextFilter.invoke(invocation)

image.png
设置RpcContext中LocalAddress、RemoteAddress、RemoteApplicationName参数

FutureFilter.invoke(invocation)

image.png
fireInvokeCallback, 具体做了什么,跳过

MonitorFilter.invoke(invocation)

image.png
方法的执行次数+1

注意,这里的invoker.invoke 会调用到ListenerInvokerWrapper.invoke(invocation),但是实际上鸟事没做

ListenerInvokerWrapper.invoke(invocation)

image.png
这里会调用到AsyncToSyncInvoker.invoke(invocation)

AsyncToSyncInvoker.invoke(invocation)

image.png

  1. 调用下层继续异步执行,下层调用的是AbstractInvoker.invoke
  2. 如果是同步的话,会阻塞

AbstractInvoker.invoke

image.png
主要调用DubboInvoker的doInvoke方法,如果doInvoker方法出现了异常,会进行包装,包装成AsyncRpcResult

DubboInvoker.doInvoke

image.png
总结一下:

  1. 从clients轮询出一个client进行数据发送,如果配置了不关心结果,则调用ReferenceCountExchangeClient的send方法
  2. 否则调用ReferenceCountExchangeClient的request方法

ReferenceCountExchangeClient.request(Object request, int timeout)

ReferenceCountExchangeClient:
image.png
request:会调用headerExchangeClient.request
image.png

HeaderExchangeClient.request

HeaderExchangeClient:
image.png
内部有:nettyClient、HeaderExchangeChannel

request:
image.png
会调用HeaderExchangeChannel.request
image.png

HeaderExchangeChannel.request

image.png
构造一个Request对象,并且会构造一个DefaultFuture对象来阻塞timeout的时间来等待结果,在构造DefaultFuture对象时,会把DefaultFuture对象和req的id存入FUTURES中,FUTURES是一个Map,当HeaderExchangeHandler接收到结果时,会从这个Map中根据id获取到DefaultFuture对象,然后返回Response。

这里的channel.send 真正调用的是AbstractPeer.send(Object message)

AbstractPeer.send(Object message)

image.png
这里会调用到AbstractClient.send(Object message, boolean sent)

AbstractClient.send(Object message, boolean sent)

image.png
NettyChannel.send(Object message, boolean sent)

NettyChannel.send(Object message, boolean sent)

image.png
调用NioSocketChannel的writeAndFlush发送数据,然后判断send如果是true,那么则阻塞url中指定的timeout时间,因为如果send是false,在HeaderExchangeChannel中会阻塞timeout时间

NioSocketChannel.writeAndFlush(Object msg)

image.png
最底层的Netty非阻塞式的发送数据

总结

最后用一张图总结:
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值