2019-11-13

1 服务在发起远程调用前,还需要经过哪些环节?能画出流程图吗?

1.1 组装url

List us = loadRegistries(false);

1.2  获取注册中心的服务

if (urls.size() ==1) {

  // 单注册中心消费

    invoker =refprotocol.refer(interfaceClass,urls.get(0));

} else {

    List> invokers =new ArrayList>();

    URLregistryURL=null;

    for (URL url :urls) {

        // 逐个获取注册中心的服务,并添加到invokers列表

        invokers.add(refprotocol.refer(interfaceClass, url));

      }

}

1.3 注册中心实例

// 创建具体注册中心实例

Registry registry =registryFactory.getRegistry(url);

1.4 底层连接通信,订阅zk节点,增加节点监听器

registry = createRegistry(url);       (工厂模式,模板模式)

1.5 cluster

// 处理订阅数据,并通过Cluster合并多个Invoker

doRefer(cluster, registry, type, url);

1.6 注册消费信息,拉取服务列表

// 注册消费信息到注册中心

registry.register(registeredConsumerUrl);

// 订阅服务提供者,路由和动态配置(第一次发起订阅时会进行一次数据拉取操作,同时触发RegistryDirectory#notify)

directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,

Constants.PROVIDERS_CATEGORY

                +"," + Constants.CONFIGURATORS_CATEGORY

                +"," + Constants.ROUTERS_CATEGORY));

// 通过Cluster合并invokers

Invoker invoker = cluster.join(directory);


2 理解Directory是如何管理Invoker的?重点关注RegistryDirectory的实现

2.1 StaticDirectory

2.2 RegistryDirectory

    2.2.1 对Invoker 做merge

    2.2.2 路由规则过滤


3 理解自定义路由是如何实现的?

根据路由规则,实现过滤invoker

invokers = router.route(invokers, getConsumerUrl(), invocation);



// copy list

routers = routers ==null ?new ArrayList() :new ArrayList(routers);

// append url router

String routerkey =url.getParameter(Constants.ROUTER_KEY);

if (routerkey !=null && routerkey.length() >0) {

    RouterFactory routerFactory =     ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(routerkey);

    routers.add(routerFactory.getRouter(url));

}

// append mock invoker selector

routers.add(new MockInvokersSelector());

routers.add(new TagRouter());

Collections.sort(routers);

this.routers = routers;

你可能感兴趣的:(2019-11-13)