Dubbo源码rpc调用流程

前言

本章基于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的生命

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值