dubbo构造invoker调用链的过程,像极了渣男撩妹

555 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

dubbo的服务提供方收到调用请求,dubbo接口会被执行,看过源码的朋友会知道,实际执行的是一个调用链,dubbo框架在接口的执行前后做了很多事情,例如接口超时会打印日志。构造这个调用链的过程像极了渣男撩妹。

渣男追女孩的时候,会对女孩说你是我最后一个女人,追到手之后,这个女孩会被抛弃,渣男继续追求下一个。这样循环往复,最终形成一个女友链。

我们看下构造调用链的源码:

private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
    //对初恋说,你是最后一个
    Invoker<T> last = invoker;
    //后宫团
    List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
  
    if (!filters.isEmpty()) {
        //一路锻炼恋爱技巧
        for (int i = filters.size() - 1; i >= 0; i--) {
            //遇到了一个女孩
            final Filter filter = filters.get(i);
             //转眼之间最后一个女孩,变成了下一个被抛弃的
            final Invoker<T> next = last;
            //对遇到的女孩说baby你是最后一个
            last = new Invoker<T>() {

                @Override
                public Class<T> getInterface() {
                    return invoker.getInterface();
                }

                @Override
                public URL getUrl() {
                    return invoker.getUrl();
                }

                @Override
                public boolean isAvailable() {
                    return invoker.isAvailable();
                }
                 
                //核心方法
                @Override
                public Result invoke(Invocation invocation) throws RpcException {
                    Result asyncResult;
                    try {
                        asyncResult = filter.invoke(next, invocation);
                    } catch (Exception e) {
                        // onError callback
                        if (filter instanceof ListenableFilter) {
                            Filter.Listener listener = ((ListenableFilter) filter).listener();
                            if (listener != null) {
                                listener.onError(e, invoker, invocation);
                            }
                        }
                        throw e;
                    }
                    return asyncResult;
                }

                @Override
                public void destroy() {
                    invoker.destroy();
                }

                @Override
                public String toString() {
                    return invoker.toString();
                }
            };
        }
    }
    //链条打造完成
    return new CallbackRegistrationInvoker<>(last, filters);
}

渣男虽然换了很多女朋友,但他会保存这些女人的电话号码,在20年后的一个寂寞而又无聊的午后,依次打电话过去,不管那个女人是在大洋彼岸,还是海峡的另一面。

static class CallbackRegistrationInvoker<T> implements Invoker<T> {

        private final Invoker<T> filterInvoker;
        private final List<Filter> filters;

        public CallbackRegistrationInvoker(Invoker<T> filterInvoker, List<Filter> filters) {
            this.filterInvoker = filterInvoker;
            this.filters = filters;
        }

        @Override
        public Result invoke(Invocation invocation) throws RpcException {
            //从现女友到初恋,依次追忆一下
            Result asyncResult = filterInvoker.invoke(invocation);

            asyncResult = asyncResult.whenCompleteWithContext((r, t) -> {
               //找找前女友们的联系方式,能找到的就打电话过去
              for (int i = filters.size() - 1; i >= 0; i--) {
                    Filter filter = filters.get(i);
                    // onResponse callback,说不准又会发生点什么
                    if (filter instanceof ListenableFilter) {
                        Filter.Listener listener = ((ListenableFilter) filter).listener();
                        if (listener != null) {
                            if (t == null) {
                                listener.onResponse(r, filterInvoker, invocation);
                            } else {
                                listener.onError(t, filterInvoker, invocation);
                            }
                        }
                    } else {
                        filter.onResponse(r, filterInvoker, invocation);
                    }
                }
            });
            return asyncResult;
        }
}

组成调用链的8个Filter

我们看下TimeoutFilter的源码:

这个Filter类中有一个invoke()方法,和一个Listener的内部实现类。invoker方法只是做了下 invoker的简单调用,而Listener内的onResponse()方法则有较多的处理逻辑,会判断下接口执行是否超时。

下面是正文:

如果你觉得意犹未尽,那就动动小手关注俺!