Dubbo中Directory解析

Directory代表多个Invoker,可以把它看成List

Directory接口

Directory接口继承了Node接口:

1234567
public interface Directory<T> extends Node {    //获取服务类型    Class<T> getInterface();

//invoker列表,服务的列表    List<Invoker<T>> list(Invocation invocation) throws RpcException;}

AbstractDirectory

默认实现为AbstractDirectory:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
public abstract class AbstractDirectory<T> implements Directory<T> {

// 日志输出    private static final Logger logger = LoggerFactory.getLogger(AbstractDirectory.class);	//服务url    private final URL url ;    private volatile boolean destroyed = false;	//消费者url    private volatile URL consumerUrl ;    //路由	private volatile List<Router> routers;

public AbstractDirectory(URL url) {        this(url, null);    }

public AbstractDirectory(URL url, List<Router> routers) {    	this(url, url, routers);    }

public AbstractDirectory(URL url, URL consumerUrl, List<Router> routers) {        if (url == null)            throw new IllegalArgumentException("url == null");        this.url = url;        this.consumerUrl = consumerUrl;        setRouters(routers);    }    //对list方法的默认实现    public List<Invoker<T>> list(Invocation invocation) throws RpcException {        if (destroyed){            throw new RpcException("Directory already destroyed .url: "+ getUrl());        }        //获取Invoker列表的具体实现由具体子类实现        List<Invoker<T>> invokers = doList(invocation);        //路由        List<Router> localRouters = this.routers; // local reference        if (localRouters != null && localRouters.size() > 0) {            for (Router router: localRouters){                try {                    if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, true)) {                    	//路由                        invokers = router.route(invokers, getConsumerUrl(), invocation);                    }                } catch (Throwable t) {                    logger.error("Failed to execute router: " + getUrl() + ", cause: " + t.getMessage(), t);                }            }        }        return invokers;    }

public URL getUrl() {        return url;    }

public List<Router> getRouters(){        return routers;    }

public URL getConsumerUrl() {		return consumerUrl;	}

public void setConsumerUrl(URL consumerUrl) {		this.consumerUrl = consumerUrl;	}	//构造中调用的设置路由的方法    protected void setRouters(List<Router> routers){        // copy list        routers = routers == null ? new  ArrayList<Router>() : new ArrayList<Router>(routers);        // append url router    	String routerkey = url.getParameter(Constants.ROUTER_KEY);        //指定了router,就使用制定的router来获取扩展实现        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());        Collections.sort(routers);    	this.routers = routers;    }

public boolean isDestroyed() {        return destroyed;    }

public void destroy(){        destroyed = true;    }	//子类实现具体的获取invoker列表    protected abstract List<Invoker<T>> doList(Invocation invocation) throws RpcException ;

}

Directory具体的实现有两个RegistryDirectory注册目录服务和StaticDirectory静态目录服务。

RegistryDirectory

RegistryDirectory实现了NotifyListener接口,因此他本身也是一个监听器,可以在服务变更时接受通知,消费方要调用远程服务,会向注册中心订阅这个服务的所有的服务提供方,订阅的时候会调用notify方法,进行invoker实例的重新生成,也就是服务的重新引用。在服务提供方有变动时,也会调用notify方法,有关notify方法在Dubbo中订阅和通知解析那篇文章中已经解释,不做重复。subscribe方法也不做重复解释。

StaticDirectory

静态目录服务。

时间: 2024-11-09 21:51:59

Dubbo中Directory解析的相关文章

Dubbo中暴露服务的过程解析

dubbo暴露服务有两种情况,一种是设置了延迟暴露(比如delay="5000"),另外一种是没有设置延迟暴露或者延迟设置为-1(delay="-1"): 设置了延迟暴露,dubbo在Spring实例化bean(initializeBean)的时候会对实现了InitializingBean的类进行回调,回调方法是afterPropertySet(),如果设置了延迟暴露,dubbo在这个方法中进行服务的发布. 没有设置延迟或者延迟为-1,dubbo会在Spring实例

Dubbo中集群Cluster,负载均衡,容错,路由解析

Dubbo中的Cluster可以将多个服务提供方伪装成一个提供方,具体也就是将Directory中的多个Invoker伪装成一个Invoker,在伪装的过程中包含了容错的处理,负载均衡的处理和路由的处理.这篇文章介绍下集群相关的东西,开始先对着文档解释下容错模式,负载均衡,路由等概念,然后解析下源码的处理.(稍微有点乱,心情不太好,不适合分析源码.) 集群的容错模式 Failover Cluster 这是dubbo中默认的集群容错模式 失败自动切换,当出现失败,重试其它服务器. 通常用于读操作,

Dubbo中SPI扩展机制解析

dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name,可以通过name找到具体的实现. 每个扩展点都有一个@Adaptive实例,用来注入到依赖这个扩展点的某些类中,运行时通过url参数去动态判断最终选择哪个Extension实例用. dubbo的SPI扩展机制增加了对扩展点自动装配(类似IOC)和自动包装(类似AOP)的支持. 标注了@Activat

Dubbo中编码和解码的解析

(这里做的解析不是很详细,等到走完整个流程再来解析)Dubbo中编解码的工作由Codec2接口的实现来处理,回想一下第一次接触到Codec2相关的内容是在服务端暴露服务的时候,根据具体的协议去暴露服务的步骤中,在DubboProtocol的createServer方法中: 1234567891011 private ExchangeServer createServer(URL url) { ... //这里url会添加codec=dubbo url = url.addParameter(Con

Dubbo中订阅和通知解析

Dubbo中关于服务的订阅和通知主要发生在服务提供方暴露服务的过程和服务消费方初始化时候引用服务的过程中. 服务引用过程中的订阅和通知 在服务消费者初始化的过程中,会有一步是进行服务的引用,具体的代码是在RegistryProtocol的refer方法: 12345678910111213141516171819 public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException { url =

Dubbo中服务消费者和服务提供者之间的请求和响应过程

服务提供者初始化完成之后,对外暴露Exporter.服务消费者初始化完成之后,得到的是Proxy代理,方法调用的时候就是调用代理. 服务消费者经过初始化之后,得到的是一个动态代理类,InvokerInvocationHandler,包含MockClusterInvoker,MockClusterInvoker包含一个RegistryDirectory和FailoverClusterInvoker. Java动态代理,每一个动态代理类都必须要实现InvocationHandler这个接口,并且每一

Dubbo中对Spring配置标签扩展

Spring提供了可扩展Schema的支持,完成一个自定义配置一般需要以下步骤: 设计配置属性和JavaBean 编写XSD文件 编写NamespaceHandler和BeanDefinitionParser完成解析工作 编写spring.handlers和spring.schemas串联起所有部件 在Bean文件中应用 dubbo中所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象. 下面我们就用dubb

【Rest】在Dubbo中开发REST风格的远程调用(RESTful Remoting)

目录 概述 REST的优点 应用场景 快速入门 标准Java REST API:JAX-RS简介 REST服务提供端详解 HTTP POST/GET的实现 Annotation放在接口类还是实现类 JSON.XML等多数据格式的支持 中文字符支持 XML数据格式的额外要求 定制序列化 配置REST Server的实现 获取上下文(Context)信息 配置端口号和Context Path 配置线程数和IO线程数 配置长连接 配置最大的HTTP连接数 配置每个消费端的超时时间和HTTP连接数 GZ

Dubbo服务框架解析(一)

公司的一个项目的分布式系统的服务管理,使用了阿里的服务框架Dubbo,因此这里准备对服务框架进行了介绍. Dubbo服务框架可以使得java分布式系统之间进行解耦,使用一个服务注册中心来统一管理服务的信息,服务提供者提供注册中心进行注册,而服务消费者可以透明地订阅和消费服务.并支持服务的路由.过滤.负载均衡等,支持多种通讯协议及NIO框架,是一个灵活性和扩展性非常棒的服务管理框架. 本文以github中当前版本2.5.4的源码来分析. 为了支持更灵活的扩展性,当前dubbo拆分了非常多的proj