Dubbo源码分析(四)|服务调用

本文详细解析了Dubbo框架中服务调用的具体流程,包括代理类方法调用、服务降级、负载均衡策略、容错机制以及远程调用过程。通过分析,读者能够深入理解Dubbo的服务调用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、服务调用

1、服务调用
1//开始调用代理类方法
DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy
String hello = demoService.sayHello("world");  
  --Proxy0.sayHello()//调用上节服务引用最后生成的代理类的方法
   --InvocationHandler.invoke(this, methods[0], arrobject);//传入代理类本身,调用方法和调用参数
    --MockClusterInvoker.invoke(new RpcInvocation(method, args)).recreate();//invoker类型为 MockClusterInvoker 内部封装了服务降级逻辑  RpcInvocation将请求参数和方法进行了封装
      --FailOverClusterInvoker.doInvoke()//调用FailOverInvoker。容错,失败之后重试调用
       --//负载均衡
        --AbstractClusterInvoker.select()//检查sticky 表示粘滞连接,就是让同一个服务消费者尽可能连接同一个服务提供者,只有当服务提供者不能提供服务,再进行切换
         --AbstractClusterInvoker.doselect() //当只有一个invoker,直接返回,否则,根据负载均衡策略返回对应invoker,默认是RandomLoadBalance
          --ListenerInvokerWrapper.invoke() //
           --ProtocolFilterWrapper.invoker() // 在这里面可以加入我们自己实现的过滤器Filter MyFilter implements Filter
            --DubboInvoker.doInvoke()
             --//拿到底层的ExchangeClent,之后开始远程调用
                // 获取异步配置,判断是否是异步调用
                boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
                // isOneway 为 true,表示“单向”通信
                boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
                //超时时间,默认1000
                int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
                // 异步无返回值
                if (isOneway) {
                    boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
                    // 发送请求
                    currentClient.send(inv, isSent);
                    // 设置上下文中的 future 字段为 null
                    RpcContext.getContext().setFuture(null);
                    // 返回一个空的 RpcResult
                    return new RpcResult();
                } else if (isAsync) { // 异步有返回值
                    // 发送请求,并得到一个 ResponseFuture 实例
                    ResponseFuture future = currentClient.request(inv, timeout);
                    //这个Future对象由用户自己调用get方法,决定啥时候获取这个值,这也就是异步有返回值的情况,
                    // FutureAdapter 是一个适配器,用于将 Dubbo 中的 ResponseFuture 与 JDK 中的 Future 进行适配
                    RpcContext.getContext().setFuture(new FutureAdapter<Object>(future));
                    // 暂时返回一个空结果
                    return new RpcResult();
                } else {// 同步调用
                    RpcContext.getContext().setFuture(null);
                    // 发送请求,得到一个 ResponseFuture 实例,并调用该实例的 get 方法进行等待
                    return (Result) currentClient.request(inv, timeout).get();//同步调用过程
                     --ReferenceCountExchangeClient.request() //一个引用计数的交换层,用于最小连接数调用
                       --HeaderExchangeClient.request(Object request, int timeout)//设置超时时间的远程调用
                        --HeaderExchangeChannel.request();
                          --Request req = new Request();
                            req.setVersion("2.0.0");
                            // 设置双向通信标志为 true
                            req.setTwoWay(true);
                            // 这里的 request 变量类型为 RpcInvocation.里面封装了RPCContext的内容和调用方法和调用参数,发送出去
                            req.setData(request);
                       --NettyClient.send()
                         --AbstractPeer.send()
                          --AbstractClient.send()
                           --NettyChannel.send()
                            --NioClientSocketChannel.write()//将数据给写出去
                             --NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);
                                    ChannelPipeline pipeline = Channels.pipeline();
                                    pipeline.addLast("decoder", adapter.getDecoder());
                                    pipeline.addLast("encoder", adapter.getEncoder());//会对发送出去的数据进行编码,编码成dubbo协议的格式
                               --ExchangeCodec.encode()
                                --DubboCodeC.encodeRequestData()//调用dubbo协议encode进行encode
                                  --Hessian2ObjectOutput.serialize()//利用hession协议进行序列化     
                 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值