前言
本章基于dubbo2.7.6版本,分析rpc调用流程。
基于上一章服务暴露与引用(juejin.cn/post/721094…),一切几乎水到渠成。
笔者将一次rpc同步调用拆分为三个阶段:
1)用户代码执行rpc方法,consumer发送rpc请求给provider
2)provider处理rpc请求响应consumer
3)consumer收到响应,返回用户代码
在总结部分整理了rpc调用流程。
发送rpc请求
代理层
InvokerInvocationHandler#invoke:
1)把rpc方法的关键信息,都包装为一个RpcInvocation贯穿Invoker#invoke;
这个RpcInvocation就不细看了,目的无非是将远程调用需要的信息都封装为一个pojo,
类似于我们平常写业务代码的时候aop用的MethodInvocation。
2)执行代理Invoker,一直通到DubboInvoker;
3)result.recreate:如果发生rpc异常,抛出,否则返回rpc方法返回值;
Cluster层
ClusterInterceptor
在上一章提到过,Cluster#join返回的Invoker会被ClusterInterceptor激活扩展点包一层,但是ClusterInterceptor并没有实现Invoker,所以要用适配器模式包一遍。
AbstractCluster内部类InterceptorInvokerNode,负责适配ClusterInterceptor实现到Invoker。
protected class InterceptorInvokerNode<T> extends AbstractClusterInvoker<T> {
private AbstractClusterInvoker<T> clusterInvoker;
private ClusterInterceptor interceptor;
private AbstractClusterInvoker<T> next;
public Result invoke(Invocation invocation) throws RpcException {
Result asyncResult;
try {
// 前置拦截
interceptor.before(next, invocation);
// 执行
asyncResult = interceptor.intercept(next, invocation);
} catch (Exception e) {
// ...
throw e;
} finally {
// 后置拦截
interceptor.after(next, invocation);
}
return asyncResult.whenCompleteWithContext((r, t) -> {
// rpc请求完成回调ClusterInterceptor.Listener
if (interceptor instanceof ClusterInterceptor.Listener) {
ClusterInterceptor.Listener listener = (ClusterInterceptor.Listener) interceptor;
if (t == null) {
listener.onMessage(r, clusterInvoker, invocation);
} else {
listener.onError(t, clusterInvoker, invocation);
}
}
});
}
}
复制代码
ConsumerContextClusterInterceptor:负责创建和清理rpc上下文,配合实现隐式传参特性。
- before:发起rpc请求前,创建rpc请求上下文,清除rpc响应上下文;
- after:发起rpc请求完成,还未收到rpc响应,清除rpc请求上下文;
- onMessage:收到rpc响应,且响应成功,创建rpc响应上下文;
- onError:rpc响应失败,什么都不做;
@Activate
public class ConsumerContextClusterInterceptor implements ClusterInterceptor, ClusterInterceptor.Listener {
@Override
public void before(AbstractClusterInvoker<?> invoker, Invocation invocation) {
// 创建rpc【请求】上下文
RpcContext.getContext()
.setInvocation(invocation)
.setLocalAddress(NetUtils.getLocalHost(), 0);
if (invocation instanceof RpcInvocation) {
((RpcInvocation) invocation).setInvoker(invoker);
}
// 清除rpc【响应】上下文
RpcContext.removeServerContext();
}
@Override
public void after(AbstractClusterInvoker<?> clusterInvoker, Invocation invocation) {
// 清除rpc【请求】上下文
RpcContext.removeContext();
}
@Override
public void onMessage(Result appResponse, AbstractClusterInvoker<?> invoker, Invocation invocation) {
// 创建rpc【响应】上下文
RpcContext.getServerContext().setObjectAttachments(appResponse.getObjectAttachments());
}
@Override
public void onError(Throwable t, AbstractClusterInvoker<?> invoker, Invocation invocation) {
}
}
复制代码
其中rpc请求上下文对应RpcContext.LOCAL,rpc响应上下文对应RpcContext.SERVER_LOCAL。
对于服务调用方,
RpcContext.LOCAL的生命周期,是一次rpc请求,用户也可以在rpc方法调用前,主动初始化RpcContext.LOCAL实现隐式传参;
RpcContext.SERVER_LOCAL的生命