一、服务调用
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协议进行序列化
}