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_NAME | METHOD_NAME | LINE_NUM |
org/simonme/dubbo/demo/provider/service/impl/HelloServiceSlowImpl | sayHello | 40 |
com/alibaba/dubbo/common/bytecode/Wrapper1 | invokeMethod | 0 |
com/alibaba/dubbo/rpc/proxy/javassist/JavassistProxyFactory$1 | doInvoke | 46 |
com/alibaba/dubbo/rpc/proxy/AbstractProxyInvoker | invoke | 76 |
com/alibaba/dubbo/rpc/protocol/InvokerWrapper | invoke | 53 |
com/alibaba/dubbo/rpc/filter/ExceptionFilter | invoke | 121 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/monitor/support/MonitorFilter | invoke | 75 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/filter/TimeoutFilter | invoke | 53 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/protocol/dubbo/filter/TraceFilter | invoke | 125 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/filter/ContextFilter | invoke | 62 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/filter/GenericFilter | invoke | 112 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/filter/ClassLoaderFilter | invoke | 40 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1 | invoke | 91 |
com/alibaba/dubbo/rpc/filter/EchoFilter | invoke | 38 |
com/alibaba/dubbo/rpc/protocol/ProtocolFilterWrapper$1[Invoker] | invoke | 91 |
com/alibaba/dubbo/rpc/protocol/dubbo/DubboProtocol$1[ExchangeHandlerAdapter] | reply | 110 |
com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeHandler | handleRequest | 91 |
com/alibaba/dubbo/remoting/exchange/support/header/HeaderExchangeHandler | received | 194 |
com/alibaba/dubbo/remoting/transport/DecodeHandler | received | 53 |
com/alibaba/dubbo/remoting/transport/dispatcher/ChannelEventRunnable | run | 99 |
框图简要示意
+-------------------------+
| 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 |
+-------------------------+
大致解释一下:
- ① 在解码过后,流转至DubbooProtocol中,此环节是用了一个ExchangeHandlerAdapter的匿名内部类,主要逻辑是:查找Invoker实例 并 触发invoke调用。查找Invoker实例是从对应的Exporter实例中找到,关于Exporter的export导出过程相关可以参见《提供者如何注册服务》。
- ② 步骤1 调用的invoker是ProtocolFilterWrapper内部的匿名内部类,此处是一个调用链,此invoker实例表示调用链的头部元素,看调用栈可以发现会挨个调用下去,且此些Invoker实例都是包在filter外面,本质是filter。调用链的构造过程参见《调用链如何构建的?ProtocolFilterWrapper分析》。构造过程还是有点意思的。
- ③JavassistProxyFactory用一个Wrapper的匿名内部类对接,用动态生成代码的手段替换掉对业务代码反射调用。具体细节可以参见《反射调用是如何优化的?Wrapper的作用是什么?》。
- ④走到真正的业务代码逻辑中。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!