zoukankan      html  css  js  c++  java
  • Dubbo-RPC调用流程(图)

     
    RPC 起源
    RPC 这个概念术语在上世纪 80 年代由 Bruce Jay Nelson 提出。这里我们追溯下当初开发 RPC 的原动机是什么?在 Nelson 的论文 "Implementing Remote Procedure Calls" 中他提到了几点:
    • 简单:RPC 概念的语义十分清晰和简单,这样建立分布式计算就更容易。
    • 高效:过程调用看起来十分简单而且高效。
    • 通用:在单机计算中过程往往是不同算法部分间最重要的通信机制。
    通俗一点说,就是一般程序员对于本地的过程调用很熟悉,那么我们把 RPC 作成和本地调用完全类似,那么就更容易被接受,使用起来毫无障碍。Nelson 的论文发表于 30 年前,其观点今天看来确实高瞻远瞩,今天我们使用的 RPC 框架基本就是按这个目标来实现的。
    Nelson 的论文中指出实现 RPC 的程序包括 5 个部分:
    • User
    • User-stub
    • RPCRuntime
    • Server-stub
    • Server
    pack:包装
     
     
    RPC 工作原理
    RPC的设计由Client,Client stub,Network ,Server stub,Server构成。 其中Client就是用来调用服务的,Cient stub是用来把调用的方法和参数序列化的(因为要在网络中传输,必须要把对象转变成字节),Network用来传输这些信息到Server stub, Server stub用来把这些信息反序列化的,Server就是服务的提供者,最终调用的就是Server提供的方法。
    1. Client像调用本地服务似的调用远程服务;
    2. Client stub接收到调用后,将方法、参数序列化
    3. 客户端通过sockets将消息发送到服务端
    4. Server stub 收到消息后进行解码(将消息对象反序列化)
    5. Server stub 根据解码结果调用本地的服务
    6. 本地服务执行(对于服务端来说是本地执行)并将结果返回给Server stub
    7. Server stub将返回结果打包成消息(将结果消息对象序列化)
    8. 服务端通过sockets将消息发送到客户端
    9. Client stub接收到结果消息,并进行解码(将结果消息反序列化)
    10. 客户端得到最终结果。
     
     
     
    Dubbo中的RPC调用流程图
     
    Dubbo官网
     
     
     
    一、客户端执行流程
    执行main(String[]) 
    首先服务消费者通过代理对象 Proxy 发起远程调用,即demoService是一个代理bean,执行proxy0.sayHello(String) ,在sayHello方法中当执行到handler.invoke(this, methods[0], args)时
    1.调用InvocationHandler
             执行InvokerInvocationHandler.invoke(Object, Method, Object[])
    2.调用invoker
             执行MockClusterInvoker<T>.invoke(Invocation)
             执行服务降级FailoverClusterInvoker<T>(AbstractClusterInvoker<T>).invoke(Invocation)
    执行RegistryDirectory$InvokerDelegate<T>(InvokerWrapper<T>).invoke(Invocation) 
    3.过滤器链处理
    ConsumerContextFilter.invoke(Invoker<?>, Invocation) 
    FutureFilter.invoke(Invoker<?>, Invocation) 
    MonitorFilter.invoke(Invoker<?>, Invocation)
    4.调用invoker
    ListenerInvokerWrapper<T>.invoke(Invocation)
    DubboInvoker<T>(AbstractInvoker<T>).invoke(Invocation)
    5.调用ExchangeClient
    ReferenceCountExchangeClient.request(Object, int) 
    HeaderExchangeClient.request(Object, int) 
    6.执行ExchangeChannel
             HeaderExchangeChannel.request(Object, int),执行channel.send方法向服务端发起请求


    二、服务提供者执行流程
    1.当服务端接收到来自客户端的请求后,开始执行ChannelEventRunnable中的run() 方法
    2.执行ChannelHandler
    DecodeHandler.received(Channel, Object) 
    HeaderExchangeHandler.received(Channel, Object)
    HeaderExchangeHandler.handleRequest(ExchangeChannel, Request) 
    3.执行Protocol
            DubboProtocol$1.reply(ExchangeChannel, Object) 
    4.过滤器链处理
    EchoFilter.invoke(Invoker<?>, Invocation)
    ClassLoaderFilter.invoke(Invoker<?>, Invocation) 
    GenericFilter.invoke(Invoker<?>, Invocation) 
    ContextFilter.invoke(Invoker<?>, Invocation)
    TraceFilter.invoke(Invoker<?>, Invocation) 
    TimeoutFilter.invoke(Invoker<?>, Invocation) 
    MonitorFilter.invoke(Invoker<?>, Invocation)
    ExceptionFilter.invoke(Invoker<?>, Invocation) 
    5.执行Invoker调用
    RegistryProtocol$InvokerDelegete<T>(InvokerWrapper<T>).invoke(Invocation)
    DelegateProviderMetaDataInvoker<T>.invoke(Invocation) 
    6.代理类调用
    JavassistProxyFactory$1(AbstractProxyInvoker<T>).invoke(Invocation) 
    7.Wrapper调用方法
            Wrapper1.invokeMethod(Object, String, Class[], Object[]) 
    8.执行Impl的调用
            DemoServiceImpl.sayHello(String)
     
    说明:
    服务消费者执行如下代码时
    DemoService demoService = (DemoService) context.getBean("demoService"); 
    String hello = demoService.sayHello("world"); 
    获得demoService代理类,执行hello方法直接调用其代理类的sayHello方法
    public java.lang.String sayHello(java.lang.String arg0){
        Object[] args = new Object[1]; 
        args[0] = ($w)$1; 
        Object ret = handler.invoke(this, methods[0], args); 
        return (java.lang.String)ret;
    }
    handler是一个InvokerInvocationHandler类型,InvocationHandler是其接口
     
  • 相关阅读:
    20145229吴姗珊《信息安全系统设计基础》第3周学习总结
    20145229《信息安全系统设计基础》第2周学习总结
    20145207 myeclipse测试
    20145207 ms11_050漏洞攻击
    20145207 ms08_067攻击实验
    20145207《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    20145207《Java程序设计》第7周学习总结
    20145207李祉昂《网络对抗技术》恶意代码分析
    20145207《Java程序设计》第6周学习总结
    20145207《网络对抗》免杀原理与实践
  • 原文地址:https://www.cnblogs.com/caoxb/p/13140287.html
Copyright © 2011-2022 走看看