Dubbo Directory#
简介#
集群容错源码包含四个部分,分别是服务目录 Directory、服务路由 Router、集群 Cluster 和负载均衡 LoadBalance。
服务目录中存储了一些和服务提供者有关的信息,通过服务目录,服务消费者可获取到服务提供者的信息,比如 ip、端口、服务协议等
服务目录在获取注册中心的服务配置信息后,会为每条配置信息生成一个
Invoker对象,并把这个Invoker对象存储起来,这个Invoker才是服务目录最终持有的对象服务目录可以看做是
Invoker集合,且这个集合中的元素会随注册中心的变化而进行动态调整
继承体系#
服务目录目前内置的实现有两个,分别为 StaticDirectory 和 RegistryDirectory,它们均是 AbstractDirectory 的子类

源码分析#
AbstractDirectory+list(Invocation invocation):
调用
doList获取Invoker列表根据
Router的getUrl返回值为空与否,以及runtime参数决定是否进行服务路由。如果runtime为true,那么每次调用服务前,都需要进行服务路由。这个对性能造成影响,配置时需要注意
1 StaticDirectory#
StaticDirectory: 静态服务目录,它内部存放的 Invoker 是不会变动的
2 RegistryDirectory#
RegistryDirectory: 是一种动态服务目录,实现了 NotifyListener 接口
当注册中心服务配置发生变化后,
RegistryDirectory可收到与当前服务相关的变化收到变更通知后,
RegistryDirectory可根据配置变更信息刷新Invoker列表
2.1 列举 Invoker#
doList(Invocation invocation): 可以看做是对 methodInvokerMap 变量的读操作
2.2 接收服务变更通知#
notify(List<URL> urls):
根据
url的category参数对url进行分门别类存储通过
toRouters和toConfigurators将url列表转成Router和Configurator列表调用
refreshInvoker方法刷新Invoker列表
2.3 刷新 Invoker 列表#
refreshInvoker(List<URL> invokerUrls):根据入参
invokerUrls的数量和协议头判断是否禁用所有的服务如果禁用,则将
forbidden设为true,并销毁所有的Invoker若不禁用,则将
url转成Invoker,得到<url, Invoker>的映射关系
进一步进行转换,得到
<methodName, Invoker 列表>映射关系进行多组
Invoker合并操作,并将合并结果赋值给methodInvokerMap。methodInvokerMap变量在doList方法中会被用到,doList会对该变量进行读操作,在这里是写操作当新的
Invoker列表生成后,销毁无用的Invoker
Map<String, Invoker<T>> toInvokers(List<URL> urls):url转成Invoker对服务提供者
url进行检测,若服务消费端的配置不支持服务端的协议,或服务端url协议头为empty时,toInvokers均会忽略服务提供方url合并
url访问缓存,尝试获取与
url对应的invoker如果缓存命中,直接将
Invoker存入newUrlInvokerMap中即可如果未命中,则需新建
Invoker
toMethodInvokers(Map<String, Invoker<T>> invokersMap): 方法名 ->Invoker列表对入参进行遍历,然后从
Invoker的url成员变量中获取methods参数,并切分成数组。随后以方法名为键,Invoker列表为值,将映射关系存储到newMethodInvokerMap中分别基于类和方法对
Invoker列表进行路由操作对
Invoker列表进行排序,并转成不可变列表
toMergeMethodInvokerMap(Map<String, List<Invoker<T>>> methodMap):生成
group到Invoker列表的映射关系表,若关系表中的映射关系数量大于1,表示有多组服务通过集群类合并每组
Invoker,并将合并结果存储到groupInvokers中将方法名与
groupInvokers存到到result中,并返回
destroyUnusedInvokers(Map<String, Invoker<T>> oldUrlInvokerMap, Map<String, Invoker<T>> newUrlInvokerMap): 删除无用Invoker通过
newUrlInvokerMap找出待删除Invoker对应的url,并将url存入到deleted列表中再遍历
deleted列表,并从oldUrlInvokerMap中移除相应的Invoker,销毁之
刷新 Invoker 列表的整个过程,简单总结:
检测入参是否仅包含一个
url,且url协议头为empty若第一步检测结果为
true,表示禁用所有服务,此时销毁所有的Invoker若第一步检测结果为
false,此时将入参转为Invoker列表对上一步逻辑生成的结果进行进一步处理,得到方法名到
Invoker的映射关系表合并多组
Invoker销毁无用
Invoker