调用过程
消费端
消费端的发送请求模型如下:
调用过程总结
客户端发送请求
- 调用一个dubbo接口,此时调用的是在服务引入过程生成的动态代理对象,内部代理逻辑就是构造RpcInvocation请求参数,然后调用Invoker.invoke方法。
- Invoker会通过ClusterInvoker,依次调用服务目录Directory的list、服务路由的router、负载均衡的 select选出一个具体的Invoker,本身也会根据Cluster的配置实现对应的集群容错的处理。
- 按照顺序执行客户端的invokerFilter链,然后走到一个AsyncToSyncInvoker,内部会持有DubboInvoker.invoke方法,内部会通过NettyClient发起真正的远程调用。在其中返回的AsyncRpcResult中会持有发起调用时生成的DefaultFuture,且每个Future都绑定了一个id,在AsyncToSyncInvoker中就是调用了其get()方法来实现的Netty异步网络调用但阻塞了当前调用的业务线程。
服务端接收请求
- NettyServer收到请求之后,根据具体的协议反序列化为对象,然后按照派发策略将请求消息封装为ChannelEventRunnable发送给线程池中(DubboServerHandler)执行,IO线程返回继续处理读/写请求。
- Dubbo服务线程会判断消息类型最后执行到在DubboProtocol内部实现的ExchangeHandlerAdapter,将请求调用到期reply方法处理。
- Dubbo服务线程根据serviceKey从服务导出时存入的exporterMap中找到对应的DubboExporter,经过一系列的服务端的InvokerFilter链之后,最终通过反射调用到真正服务实现类的方法。最后通过DubboServerHandler向客户端发送结果Response。
客户端接收返回请求
- 和服务端接收请求一样,经历反序列化之后,按照派发策略派发给DubboClientHandler线程执行。
- 根据之前绑定DefaultFuture的id从本地Future的缓存Map中找到DefaultFuture,通过DefaultFuture.received(response)来唤醒阻塞在AsyncToSyncInvoker的client线程,将最后的结果返回到调用处即可。