19.被consumer端调用时的线程模型与链路

provider侧

线程模型

       +-----------------+         +-----------------+         +-----------------+
+------>   boss/         +-------->+  worker/        +--------->  dubbo          |
       |   accept        |         |  poller         |         |  serVer handler |
       +-----------------+         +-----------------+         +-----------------+

上图是默认情况,根据配置不同,可能会出现没有单独的dubbo server handler线程(池),或者某些事件处理上没有。具体不同配置对应的细节可以参见《关于dubbo中业务线程池的处理也即对ChannelHandler与Dispatcher体现的分析》。

链路

调用栈

Daemon Thread [DubboServerHandler-172.22.221.166:20880-thread-18] (Suspended (breakpoint at line 36 in HelloServiceSlowImpl))

CLASS_NAMEMETHOD_NAMELINE_NUM
org/simonme/dubbo/demo/provider/service/impl/HelloServiceSlowImplsayHello40
com/alibaba/dubbo/common/bytecode/Wrapper1invokeMethod0
com/alibaba/dubbo/rpc/proxy/javassist/JavassistProxyFactory$1doInvoke46
com/alibaba/dubbo/rpc/proxy/AbstractProxyInvokerinvoke76
com/alibaba/dubbo/rpc/protocol/InvokerWrapperinvoke53
com/alibaba/dubbo/rpc/filter/ExceptionFilterinvoke121
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/monitor/support/MonitorFilterinvoke75
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/filter/TimeoutFilterinvoke53
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/protocol/dubbo/filter/TraceFilterinvoke125
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/filter/ContextFilterinvoke62
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/filter/GenericFilterinvoke112
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/filter/ClassLoaderFilterinvoke40
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1invoke91
com/alibaba/dubbo/rpc/filter/EchoFilterinvoke38
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1[Invoker]invoke91
com/alibaba/dubbo/rpc/protocol/dubbo/DubboProtocol$1[ExchangeHandlerAdapter]reply110
com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeHandlerhandleRequest91
com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeHandlerreceived194
com/alibaba/dubbo/remoting/transport/DecodeHandlerreceived53
com/alibaba/dubbo/remoting/transport/dispatcher/ChannelEventRunnablerun99

框图简要示意

+-------------------------+
| DecodeHandler           |
|   receiVed              |
+------------+------------+
             |
             |
             |
+------------v------------+
| HeaderExchangeHandler   |
|   receiVed              |
+------------+------------+
             |
             |
             |
+------------v------------+        ①
| DubboProtocol$1.reply   |       get invoker then
|   ExchangeHandlerAdapter|  <---+call invoker.invoke(Invocation)
+------------+------------+
             |
             |
             |
+------------v------------+       ②
| ProtocolFilterWrapper$1 |       inVoke chain
|   InVoker               |  <---+invoker+filter=chain
+------------+------------+
             |
             |
             |
+------------v------------+       ③
| JavassistProxyFactory$1 |       dynmaic generate code
|   Wrapper               |  <---+replace reflect
+------------+------------+
             |
             |
             |
+------------v------------+       ④
|  bizService             |  <---business code
|  dobiz                  |
+-------------------------+

大致解释一下:

  1. ① 在解码过后,流转至DubbooProtocol中,此环节是用了一个ExchangeHandlerAdapter的匿名内部类,主要逻辑是:查找Invoker实例 并 触发invoke调用。查找Invoker实例是从对应的Exporter实例中找到,关于Exporter的export导出过程相关可以参见《提供者如何注册服务》。
  2. ② 步骤1 调用的invoker是ProtocolFilterWrapper内部的匿名内部类,此处是一个调用链,此invoker实例表示调用链的头部元素,看调用栈可以发现会挨个调用下去,且此些Invoker实例都是包在filter外面,本质是filter。调用链的构造过程参见《调用链如何构建的?ProtocolFilterWrapper分析》。构造过程还是有点意思的。
  3. ③JavassistProxyFactory用一个Wrapper的匿名内部类对接,用动态生成代码的手段替换掉对业务代码反射调用。具体细节可以参见《反射调用是如何优化的?Wrapper的作用是什么?》。
  4. ④走到真正的业务代码逻辑中。