栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Dubbo集群容错之Directory

Dubbo集群容错之Directory

1. 前言

前面的文章分析了Dubbo集群容错层之Cluster和ClusterInvoker,我们已经知道,Directory会提供可调用的服务列表,Cluster会将这一组服务聚合成单个具备集群容错能力的ClusterInvoker,上层服务还是对ClusterInvoker发起invoke调用,透明的实现了集群容错。

本文重点分析下Directory接口,Dubbo目前提供了两种实现,分别是基于注册中心的RegistryDirectory,和静态服务StaticDirectory。可以这么说,Dubbo实现服务的自动注册与发现,RegistryDirectory功不可没。

2. Directory

Directory是服务目录接口,它主要的功能就是在Consumer发起RPC调用时,根据Invocation过滤出可调用的服务给ClusterInvoker做负载均衡。

public interface Directory extends Node {

    
    Class getInterface();

    
    List> list(Invocation invocation) throws RpcException;

    // 获取所有Invoker
    List> getAllInvokers();

    // 消费者URL
    URL getConsumerUrl();

}
2.1 RegistryDirectory

RegistryDirectory是基于注册中心的服务目录,它会去注册中心订阅服务。

public void subscribe(URL url) {
    setConsumerUrl(url);
    // 注册监听
    CONSUMER_CONFIGURATION_LISTENER.addNotifyListener(this);
    serviceConfigurationListener = new ReferenceConfigurationListener(this, url);
    // 订阅服务
    registry.subscribe(url, this);
}

服务变更时会触发notify()方法,会获取到服务提供者的URL。因为服务往往都是集群部署的,所以获取到的一般都是一组URL,暂且称它为ProviderUrls。只要ProviderUrls有变更,就会将它们自动转换成对应的Invoker,例如Provider提供的是dubbo协议的服务,那么就会自动转换成DubboInvoker。

有了一组Invoker,接下来,当Consumer发起RPC调用时,就会依赖RegistryDirectory提供服务列表了,此时会调用它的doList()方法,默认情况下会返回所有的服务,但是Dubbo是支持服务路由的,你可以编写自己的路由规则,例如针对有状态的请求尽可能的调用同一台服务器。

Router是Dubbo提供的服务路由接口,Dubbo支持条件路由、文件路由和脚本路由,开发者可以基于Router实现自己的路由规则。Router被设计成链式结构,RegistryDirectory会构建RouterChain,利用SPI的自动激活特性,将激活的Router加入到RouterChain。

private RouterChain(URL url) {
    List extensionFactories = ExtensionLoader.getExtensionLoader(RouterFactory.class)
        .getActivateExtension(url, "router");
    List routers = extensionFactories.stream()
        .map(factory -> factory.getRouter(url))
        .collect(Collectors.toList());
    initWithRouters(routers);
}

Invokers会经过Router的层层过滤,最终返回的Invokers才会被用来做负载均衡。

public List> doList(Invocation invocation) {
    List> invokers = null;
    try {
        invokers = routerChain.route(getConsumerUrl(), invocation);
    } catch (Throwable t) {}
    return invokers == null ? Collections.emptyList() : invokers;
}

RegistryDirectory还有一个比较重要的方法是toInvokers(),它会将ProviderUrls自动转换成对应的Invoker,依赖的其实还是Protocol,以dubbo协议为例,那就是创建DubboInvoker,此时就会和服务端建立网络连接。

invoker = new InvokerDelegate<>(protocol.refer(serviceType, url), url, providerUrl);
2.2 StaticDirectory

StaticDirectory是一个静态的服务目录,实现很简单,不会和注册中心打交道,它内部的Invokers是在创建的时候直接指定的,什么时候会用到StaticDirectory呢?
当消费者想绕过注册中心,直接指定url,和Provider点对点直连时,就会用到StaticDirectory。

3. 总结

Directory接口用于Consumer发起RPC调用时提供服务列表,Dubbo内置了两种实现,分别是基于注册中心的RegistryDirectory,和静态服务StaticDirectory,后者在点对点直连时会用到,使用更多的是前者。
RegistryDirectory+注册中心实现了Dubbo服务自动注册与发现,RegistryDirectory会去注册中心订阅服务,然后将ProviderUrls转换成对应的Invoker,然后构建RouterChain,后续根据RPC调用的Invocation参数进行服务过滤,提供一组可用的Invokers交给LoadBalance做负载均衡。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682889.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号