Dubbo调用

0. 概述

Dubbo 服务调用过程比较复杂,包含众多步骤,比如发送请求、编解码、服务降级、过滤器链处理、序列化、线程派发以及响应请求等步骤。

1. 客户端发送请求时序图

dubbo调用什么时候掉Filter dubbo 调用_dubbo

dubbo调用什么时候掉Filter dubbo 调用_dubbo调用什么时候掉Filter_02

  • InvokerInvocationHandler.invoke
1. 对于Object中的方法toString, hashCode, equals直接调用invoker的对应方法。
2. 远程调用层是以Invocation, Result为中心, 这里根据要调用的方法以及传入的参数构建RpcInvocation对象,作为Invoker的入参。
  • MockClusterInvoker根据参数提供了三种调用策略
1. 不需要mock, 直接调用FailoverClusterInvoker。
2. 强制mock,调用mock。
3. 先调FailoverClusterInvoker,调用失败在mock。
  • FailoverClusterInvoker默认调用策略
1. 通过目录服务查找到所有订阅的服务提供者的Invoker对象。
2. 路由服务根据策略来过滤选择调用的Invokers。
3. 通过负载均衡策略LoadBalance来选择一个Invoker。
  • 执行选择的Invoker.inoker(invocation)
1. 经过监听器链,默认没有。
2. 经过过滤器链,内置实现了很多。
3. 执行到远程调用的DubboInvoker。
  • DubboInvoker
1. 根据url 也就是根据服务提供者的长连接,这里封装成交互层对象ExchangeClient供这里调用。
2. 判断远程调用类型同步,异步还是oneway模式。
3. ExchangeClient发起远程调用,底层remoting不在这里描述了。
  • 获取调用结果
1. Oneway返回空RpcResult。
2. 异步,直接返回空RpcResult, ResponseFuture回调。
3. 同步,ResponseFuture模式同步转异步,等待响应返回。

2. 服务端接收请求时序图

dubbo调用什么时候掉Filter dubbo 调用_java_03

  • DubboProtocol的requestHandler是ExchangeHandler的实现,是remoting层接收数据后的回调
1. requestHandler.replay方法接收请求消息,这里只处理远程调用消息Invocation。
2. 通过Invocation获取服务名和端口组成serviceKey=com.alibaba.dubbo.demo.DemoService:20880, 从DubboProtocol的exproterMap中获取暴露服务的DubboExporter, 在从dubboExporter 获取invoker返回。
3. 经过过滤器链。
4. 经过监听器链。
5. 到达执行真正调用的invoker, 这个invoker由代理工厂ProxyFactory.getInvoker(demoService, DemoService.class, registryUrl)创建。
  • 调用demoService实例方法,将结果封装成RpcResult返回
1. 交换层构建Response,通过Remoting层编码传输将结果响应给调用方。

3. 消费方发起请求底层通信时序图

dubbo调用什么时候掉Filter dubbo 调用_dubbo调用什么时候掉Filter_04

4. 服务提供方接收请求底层通信时序图

dubbo调用什么时候掉Filter dubbo 调用_dubbo调用什么时候掉Filter_05

5. 源码分析

本文是基于2.7.8源码进行分析的。

从 DemoService 接口的代理类开始进行分析

通过反编译,可以看到生成的代理类对象如下:

dubbo调用什么时候掉Filter dubbo 调用_dubbo_06

currentClient.request

currentClient.request 源码如下就是组装 request 然后构造一个 future 然后调用 NettyClient 发送请求。

dubbo调用什么时候掉Filter dubbo 调用_dubbo_07

因为是异步,那么这个 future 保存了之后,等响应回来了如何找到对应的 future 呢?

可以看到 Request 会生成一个全局唯一 ID,然后 future 内部会将自己和 ID 存储到一个 ConcurrentHashMap。这个 ID 发送到服务端之后,服务端也会把这个 ID 返回来,这样通过这个 ID 再去ConcurrentHashMap 里面就可以找到对应的 future ,这样整个连接就正确且完整了!

dubbo调用什么时候掉Filter dubbo 调用_远程调用_08

dubbo调用什么时候掉Filter dubbo 调用_dubbo_09

6. 总结

本篇文章主要介绍了服务调用的过程。

7. 鸣谢

Dubbo服务调用