【dubbo源码】16. 服务消费方之刷新服务列表providers

前言

刷新服务列表的原理

由于在服务消费方启动的时候监听了zk注册中心某个服务的providers节点,而服务提供方在上线或者下线的时候,都会往往该节点对应的写入或者剔除 服务信息

那么服务的某个提供方实例在上线,或者下线的时候都会以事件监听的方式通知到消费方,去根据最新的providers列表刷新自己本地的服务列表,以方便后续的服务调用。

  • 服务上线的话,消费方则会把其加到可调用的服务列表中,纳入负载均衡的范围之内
  • 服务下线的话,消费方则会把他从服务列表中剔除,下次则不会调用下线的服务实例

1. 服务列表存在哪

RegistryDirectory

image

服务消费方的服务列表都是存储在RegistryDirectory对象中,并且是一对一的关系。

服务列表的成员变量 :
// serviceUrl和invokerDelegate的映射关系
Map<String, Invoker<T>> urlInvokerMap 
// 方法名称和invoker的关系
Map<String, List<Invoker<T>>> methodInvokerMap
并且实现NotifyListener接口

同时这个类的对象也是一个监听器,监听了某服务下providers,configurators,routers的变化。

那么当远程服务列表providers节点发生改变的时候,则会调用到RegistryDirectory的notify方法去更新本地内存的服务列表。

1. 服务列表的初始化

当消费方启动的时候就会先获取到远程的服务列表,后续服务列表发生变更将会以事件通知的形式通知消费端更新服务列表。

1.1 注册监听后,会获取被监听节点的children子节点,并手动调用一次监听器的notify方法

image

获取到providers,configurators,routers的所有url


image

先根据category进行分组,依次category分组后的Url调用监听器的notify,这里的监听器类是RegistryDirectory类

image

我们先只关注providers节点的url,调进来会先判断category,放到invokerUls中

image

刷新Invokers,就是刷新服务列表

image

先把旧的服务列表存起来,再把传进来的url缓存起来

image

如果你把远程的providers都清空了,进到方法里传进来的invokerUrls就会为空,这个时候就会为了容错性不刷新服务列表,直接return

image

1.2 建立url和invoke的映射关系

image

循环providers url

image
1.2.1 合并url

接下来紧接的就是合并url,把provider的url与本机的配置信息进行合并,如果有相同的配置以consumer的配置优先

合并后的url还是要经过configurator配置的url的配置覆盖

image
image

把一些不需要更改的配置的key移除掉

image

后面吧provider的url配置全部移除掉,加入本地consumer的配置

image
1.2.2 创建invoker对象

合并完url之后还要用protocol对象的provider Url对应的Invoker对象

image

由于这里的协议是个providers节点下的dubbo协议,所以这里经过spi,获取到的protocol对象是一个包装着dubboProtocal的包装类对象,经过层层修饰最终还是会调到dubboProtocol的refer方法

image

最终返回DubboInvoker对象,第三个参数getClients(url)会涉及到netty服务端的创建,用于与服务提供方进行网络通讯,后面会详细讲

1.2.3 建立url与invoker对象的映射

存到newUrlInvokerMap中,返回

如果有invokerUrls有多个相同的url,会有缓存,先从缓存中获取invoker,如果有就会直接根据key put,如果没有就会新创建invoker,所以最终每个不同的providers url就只会对应一个invoker对象

image

建立好newUrlInvokerMap之后,赋值给RegistryDirectory的urlInvokerMap成员变量

image
RegistryDirectory的urlInvokerMap属性
// Map<url, Invoker> cache service url toinvoker mapping.
private volatile Map<String, Invoker<T>> urlInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable reference

1.2 建立服务中方法和invoke的映射关系

往往服务消费端对服务提供方的调用是由一个方法,然后走代理进行远程调用的逻辑的,所以同时还会有服务中方法和invoker的映射关系,以便快速的根据所调的方法找到对应的invoker,进行远程服务实例对应方法的调用。

image
  1. 循环urlInvokerMap的value集合,就是Invoker集合

  2. 获取invoker的url的methods的值,就是所有的接口方法,以 逗号隔开

  3. 建立映射关系,key是方法名称,value是invokeList,put到newMethodInvokerMap中

    image

其中还要根据routers节点的配置,过滤掉一些Invokes,然后再put进去,具体逻过滤的逻辑后面细讲。

image

最后对每一个方法的invoker集合进行url的排序,最后重新put进去,并且放到不可改的list中,其他地方不能更改这个服务列表。最后返回

image

返回后赋值到RegistryDirectory的成员变量methodInvokerMap中

image
RegistryDirectory的methodInvokerMap属性
//缓存本地服务列表,建立method和invokers的映射关系
// Map<methodName, Invoker> cache service method to invokers mapping.
private volatile Map<String, List<Invoker<T>>> methodInvokerMap; // The initial value is null and the midway may be assigned to null, please use the local variable

1.3 销毁不可用的invoker方法

image

就是循环之前的服务列表,如果新的服务列表里不包含这个invoker对象,就掉invoker对象的destory进行销毁工作

image

2. 服务提供方上下线通知服务消费方更新服务列表

服务列表初始化时,是用注册providers节点的监听器时,获取到children(url)后手动调用监听器的notify方法

如果某个服务上线或者下线,更改了zk的providers节点数据,就会zk通知客户端,调用监听器的notify方法,并传入更新后的children(url),之后的逻辑和手动调用监听器的notify方法是一样的,根据urls重新构建
RegistryDirectory类的methodInvokerMap,urlInvokerMap。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容