Dubbo 服务端调用流程(02)

1 发送消息的整体流程

1.1 主要调用流程

  1. 调用远程接口,执行对应代理 (代理构建)
  2. 代理中调用Filter过滤链、执行Cluster(Invoker)(执行链的构建和执行)
  3. ClusterInvoker中先路由出一批Invoker列表、在负载均衡出唯一的调用者Invoker(筛选唯一Invoker)
  4. Invoker调用交换层进行网络发送数据
  5. 交换层发送数据、协议编码

2 代理创建

Deployer 、RefrenceCache、RefrenceConfig、Protocol、Invoker、Directory、Listener、JavasissitProxy

  1. DubboDeployApplicationListener Spring启动监听器启动进行初始化操作 启动ModuleDeployer
  2. DefaultModuleDeployer#start Deployer启动中进行导入需要的服务引用
  3. SimpleReferenceCache从缓存中获取服务引用、如果没有进行创建服务的引用
  4. ReferenceConfig中进行初始化创建服务的引用,createInvokerForRemote创建服务的invoker引用,通过protocol创建服务引用(Invoker)
  5. RegistryProtocol#doRefer 创建ClusterInvoker,interceptInvoker方法中出发对应的监听器
    MigrationRuleListener
  6. ServiceDiscoveryRegistryDirectory 监听器中触发Directory订阅注册中心
  7. ServiceDiscoveryRegistry#subscribeURLs订阅注册中心触发监听器ServiceInstancesChangedListener
  8. 在监听器中获取远程元数据、接着创建对应的代理类

3 构建filterInvoker链

filterInvoker的数据结构

filterInvoker的数据结构 执行流程

FilterChainBuilder.CopyOfFilterChainNode#invoke执行

  @Override
        public Result invoke(Invocation invocation) throws RpcException {
            Result asyncResult;
            try {
                InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
                // filter: ConsumerContextFilter
                // nextNode: FilterChainBuilder.CopyOfFilterChainNode
                asyncResult = filter.invoke(nextNode, invocation);
            } catch (Exception e) {
                InvocationProfilerUtils.releaseDetailProfiler(invocation);
                if (filter instanceof ListenableFilter) {
                    ListenableFilter listenableFilter = ((ListenableFilter) filter);
                    try {
                        Filter.Listener listener = listenableFilter.listener(invocation);
                        if (listener != null) {
                            listener.onError(e, originalInvoker, invocation);
                        }
                    } finally {
                        listenableFilter.removeListener(invocation);
                    }
                } else if (filter instanceof FILTER.Listener) {
                    FILTER.Listener listener = (FILTER.Listener) filter;
                    listener.onError(e, originalInvoker, invocation);
                }
                throw e;
            } finally {

            }
            return asyncResult;
        }

ConsumerContextFilter#invoke

  @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
              ...
            // FilterChainBuilder.CopyOfFilterChainNode.invoke
            return invoker.invoke(invocation);
        } finally {
            RpcContext.restoreServiceContext(originServiceContext);
        }
    }
  @Override
        public Result invoke(Invocation invocation) throws RpcException {
            Result asyncResult;
            try {
                InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke.");
                // filter: FutureFilter
                // nextNode: FilterChainBuilder.CopyOfFilterChainNode
                asyncResult = filter.invoke(nextNode, invocation);
            } catch (Exception e) {
                InvocationProfilerUtils.releaseDetailProfiler(invocation);
                if (filter instanceof ListenableFilter) {
                    ListenableFilter listenableFilter = ((ListenableFilter) filter);
                    try {
                        Filter.Listener listener = listenableFilter.listener(invocation);
                        if (listener != null) {
                            listener.onError(e, originalInvoker, invocation);
                        }
                    } finally {
                        listenableFilter.removeListener(invocation);
                    }
                } else if (filter instanceof FILTER.Listener) {
                    FILTER.Listener listener = (FILTER.Listener) filter;
                    listener.onError(e, originalInvoker, invocation);
                }
                throw e;
            } finally {

            }
            return asyncResult;
        }
  1. FilterChainBuilder.CopyOfFilterChainNode作为节点的包装节点包含两个 filter和nextNode
  2. filter.invoke执行的最后会执行nextNode.invoke,而nextNode又是FilterChainBuilder.CopyOfFilterChainNode(包含下一个filter和nextNode)的节点
  3. 这样通过节点中filter调用下个节点,下个节点的过滤器再调用下下个节点,形成啦filter执行链路

4 获取最原始的Invoker列表

  1. 订阅注册中心或者注册中心中被引用的服务发生变化,触发对应的监听器
  2. 监听器中刷新被引用的服务缓存,刷新routerChain中的Invoker列表

5 筛选唯一Invoker的流程(路由 )

AbstractClusterInvoker#invoke

  @Override
    public Result invoke(final Invocation invocation) throws RpcException {
        checkWhetherDestroyed();

        // binding attachments into invocation.
//        Map<String, Object> contextAttachments = RpcContext.getClientAttachment().getObjectAttachments();
//        if (contextAttachments != null && contextAttachments.size() != 0) {
//            ((RpcInvocation) invocation).addObjectAttachmentsIfAbsent(contextAttachments);
//        }

        InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Router route.");
        List<Invoker<T>> invokers = list(invocation);        //1  获取invoker执行列表(经过路由列表、和指定策略的路由,筛选符合条件的Invoker列表)
        InvocationProfilerUtils.releaseDetailProfiler(invocation);
        // 获取负载均衡器
        LoadBalance loadbalance = initLoadBalance(invokers, invocation); // 2 初始化负载均衡器
        RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);

        InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Cluster " + this.getClass().getName() + " invoke.");
        try {
            return doInvoke(invocation, invokers, loadbalance);      //3 通过负载均衡筛选出唯一的Invoker
        } finally {
            InvocationProfilerUtils.releaseDetailProfiler(invocation);
        }
    }

stateRouter过滤之后再有普通路由列表依次进行过滤

6 筛选唯一Invoker的流程(负载均衡 )

获取唯一的负载均衡器

使用负载均衡器获取唯一的Invoker

随机负载均衡器

(支持设置invoker权重)

7 Invoker执行交换层进行数据的发送

DubboInvoker 执行ExchangeClient发送Channel数据

8 BitList分析

存储Invoker列表用的是BitList,方便对路由和负载均衡对结果的筛选和缓存。

  1. BitList由三部分组成 rootSet、originList、tailList
  2. originList是一个原始的最全的元素结合,
  3. rootSet 标识originList中哪些元素是存在的哪些是不存在的,通过对rootSet的位操作来修改或者获取Invoker结果。通过对rootSet的与或运算来对元素进行筛选和操作BitSet计算效率高、内存占用小
  4. tailList 对最终结果拼接其他元素的列表

9 后续章节

  1. exchangeclient发送数据的详细流程(建立连接、发送数据、协议编码等)
  2. 服务端接受消息的处理流程(解码、线程模型)
  3. 服务端启动流程
  4. 责任链的应用
  5. 监听器的应用

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值