dubbo 2.6.0 调用过程

异常堆栈

 at com.service.lmpl.client.ChatServiceImpl.getTalkMsg(LrbServiceMsgServiceImpl.java:1299)
 at com.alibaba.dubbo.common.bytecode.Wrapper80.invokeMethod(Wrapper80.java)
 at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:45)
 at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:71)
 at com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:48)
 at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:52)
 at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:61)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:74)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:41)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:71)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:131)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:37)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:37)
 at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:68)
 at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:98)
 at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:96)
 at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:168)
 at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:50)
 at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:79)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
 at java.lang.Thread.run(Thread.java:750)

让我们分析这个异常堆栈,从下往上讲解 Dubbo 的调用过程:

  1. 线程启动 (java.lang.Thread.run):

    • 调用链的起点是 Java 线程的启动。Thread.run 方法是所有线程执行的入口。
  2. 线程池执行 (ThreadPoolExecutor$Worker.run):

    • 线程池中的工作线程开始执行任务。这里使用的是 ThreadPoolExecutor,它管理并调度线程池中的线程。
  3. 线程池调度 (ThreadPoolExecutor.runWorker):

    • ThreadPoolExecutorrunWorker 方法调度并执行具体的任务。这个任务对应的是一个 RPC 请求的处理。
  4. 通信层处理 (ChannelEventRunnable.run):

    • ChannelEventRunnable 是 Dubbo 中的一个类,用于处理通信通道中的事件。在这里,它执行了网络事件的处理。
  5. 解码器处理 (DecodeHandler.received):

    • DecodeHandler 是 Dubbo 中的一个处理器,用于对收到的数据进行解码。它将解码后的数据传递给下一个处理器。
  6. 请求处理 (HeaderExchangeHandler.received):

    • HeaderExchangeHandler 负责处理解码后的请求,主要是对请求进行处理和响应。
  7. 协议层调用 (HeaderExchangeHandler.handleRequest):

    • 这个方法具体负责处理接收到的请求,并调用相应的服务方法。
  8. Dubbo 协议 (DubboProtocol$1.reply):

    • DubboProtocol 是 Dubbo 中的核心协议处理器,负责将调用分发到具体的服务实现上。这里的 reply 方法是处理响应的。
  9. 过滤器链调用 (ProtocolFilterWrapper$1.invoke):

    • 这个调用标志着过滤器链的开始,过滤器会逐层包裹并处理请求。过滤器链的执行顺序是由内向外的顺序(先执行内部,再执行外部)。
  10. 各类过滤器:

    • EchoFilter.invoke, ClassLoaderFilter.invoke, GenericFilter.invoke, ContextFilter.invoke, TraceFilter.invoke, TimeoutFilter.invoke, MonitorFilter.invoke, ExceptionFilter.invoke:这些过滤器在请求被处理前后插入额外的逻辑,比如日志、监控、超时处理等。
  11. 服务调用 (InvokerWrapper.invoke):

    • InvokerWrapper 负责调用实际的服务实现,它是一个 Invoker 的包装器。
  12. 元数据包装器 (DelegateProviderMetaDataInvoker.invoke):

    • DelegateProviderMetaDataInvoker 是对服务提供者的元数据进行包装和管理。
  13. 抽象代理调用 (AbstractProxyInvoker.invoke):

    • AbstractProxyInvoker 是服务调用的抽象层,通过它来调用实际的服务实现。
  14. 代理调用 (JavassistProxyFactory$1.doInvoke):

    • 这是 Dubbo 动态代理生成的代理类,通过 Javassist 技术生成,用来代理实际的服务调用。
  15. 动态代理方法调用 (Wrapper80.invokeMethod):

    • Wrapper80 是由 Dubbo 生成的动态代理类的字节码,负责调用目标方法。
  16. 业务逻辑层 (ChatServiceImpl.getTalkMsg):

    • 最终,调用到了业务代码中的 ChatServiceImpl.getTalkMsg 方法,这里是具体的业务逻辑执行点,也是异常发生的地方。

服务地址

zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=app-backend-api&dubbo=2.6.0&interface=com.interface.api.client.IndexApi&logger=slf4j&methods=getCityList,getToken&pid=147470&register.ip=172.17.0.1&revision=0.0.1-SNAPSHOT&side=consumer&timeout=3000&timestamp=1726526308198

这是一条 Dubbo 框架中使用的服务引用地址,采用了 ZooKeeper 作为注册中心。下面我们逐一分析地址中的各个部分及其含义:

  1. 协议和注册中心地址

    • zookeeper://127.0.0.1:2181
      • 协议(scheme)zookeeper,表示使用 ZooKeeper 作为注册中心协议。
      • 注册中心地址127.0.0.1:2181,表示注册中心的主机地址是本地(127.0.0.1),端口是 2181,这是 ZooKeeper 的默认端口。
  2. 服务路径

    • /com.alibaba.dubbo.registry.RegistryService
      • 服务接口全限定名com.alibaba.dubbo.registry.RegistryService,这是在注册中心中存储服务信息的路径,表示正在引用或注册的服务接口。
  3. 查询参数(Query Parameters)

    • application=app-backend-api
      • 应用名称app-backend-api,标识当前应用的名称。
    • dubbo=2.6.0
      • Dubbo 版本2.6.0,表示使用的 Dubbo 框架版本。
    • interface=com.interface.api.client.IndexApi
      • 服务接口com.interface.api.client.IndexApi,表示正在引用或提供的服务接口的全限定名。
    • logger=slf4j
      • 日志框架slf4j,指定使用 SLF4J 作为日志记录框架。
    • methods=getCityList,getToken
      • 方法列表:列出了该服务接口提供的所有方法名称,供消费者调用。
    • pid=147470
      • 进程 ID147470,表示当前应用进程的进程号。
    • register.ip=172.17.0.1
      • 注册 IP172.17.0.1,表示在注册中心中登记的 IP 地址,可能是容器或虚拟机的内部 IP。
    • revision=0.0.1-SNAPSHOT
      • 服务版本0.0.1-SNAPSHOT,表示服务接口的版本号,通常用于管理服务的迭代和兼容性。
    • side=consumer
      • 角色consumer,表示当前应用在该服务中扮演的是消费者的角色,而非提供者。
    • timeout=3000
      • 超时时间3000,表示服务调用的超时时间为 3000 毫秒(3 秒)。
    • timestamp=1726526308198
      • 时间戳1726526308198,表示注册或引用服务的时间戳,单位为毫秒。这个时间戳可以用于跟踪服务的注册时间。

总结

  • 这条地址表示一个名为 app-backend-api 的应用,作为消费者(side=consumer),使用 Dubbo 2.6.0 框架,通过 ZooKeeper 注册中心(位于 127.0.0.1:2181)引用了服务接口 com.interface.api.client.IndexApi
  • 该服务接口的版本是 0.0.1-SNAPSHOT,提供了多个方法供调用。
  • 应用使用 SLF4J 作为日志框架,设置了服务调用的超时时间为 3 秒。
  • 进程 ID 和注册 IP 提供了应用的运行时信息,时间戳记录了引用服务的具体时间。

通过解析这些信息,可以更好地理解应用与服务之间的调用关系,以及在分布式系统中的部署和配置情况。