dubbo3 元数据中心-实例级服务注册发现

本文中使用zookeeper做为dubbo的注册中心和元数据中心。

配置

开启元数据中心remote模式的配置有两种:
springboot应用,可以在application.yaml中添加配置

dubbo:
	application:
		metadataType: remote # 开启元数据中心"remote"模式,可以切换为"local"模式
	metadata-report:
		parameters:
			"sync.report": true # 以同步的方式写入元数据,方便调试

dubbo原生应用可以在dubbo.properties中添加配置

dubbo.metadata.storage-type=remote

provider 服务注册

provider在启动的时候,会先往元数据中心写入DubboService(接口)的元数据,然后再是DubboService接口和应用服务的映射信息,最后再是写应用服务实例的元数据和服务实例节点信息。对应的zookeeper 节点路径如下:

数据项 节点路径 描述
DubooService接口元数据 路径格式:/dubbo/metadata/{interface}/{version}/{group}/{side}/{application}
路径示例:/dubbo/metadata/com.saleson.api.Service/v1.0/test/provider/provider-demo
local模式也会写,但是没有找到哪里有使用
DubboService接口和应用服务的映射信息 路径格式:/dubbo/mapping/{interface}
路径示例:/dubbo/mapping/com.saleson.api.Service
local模式也会写
应用服务实例的元数据 路径格式:/dubbo/metadata/{application}/{metadataVevision}
路径示例:/dubbo/metadata/provider-demo/19bb9fd…
只在remote模式下会写数据
服务实例节点信息 路径格式:/services/{application}/{instance-ip:port}
路径示例:/services/provider-demo/192.168.0.12:20880
用于实例的发现,这是往注册中心写的数据

provider在启动时会往元数据中心写DubooService接口元数据、DubboService接口和应用服务的映射信息、应用服务实例的元数据这三项数据;consumer可以通过DubboService接口和应用服务的映射信息、应用服务实例的元数据以及注册中心的服务实例节点信息来完成实例级的服务发现。

写DubooService接口元数据和DubboService接口和应用服务的映射信息的时序图:
在这里插入图片描述

写应用服务实例的元数据以及服务实例节点信息的时序图:
在这里插入图片描述

consumer 服务发现

实例级的服务发现逻辑主要是从ServiceDiscoveryRegistryDirectory.subscribe()方法开始,经过ServiceDiscoveryRegistory,ServiceInstancesChangedListener, RemoteMetadataServiceImpl, ZookeeperMetadataReport等相关核心类后最终将拼装好的InstanceAddressURL返回给ServiceDiscoveryRegistryDirectory,并通过其notify()方法完成URL 到 Invoker的转换;整个过程可以分为如下几个步骤:

1.获取DubboService的提供者应用名称列表
调用MetadataServiceNameMapping.getAndListenServices()方法从元数据中心/dubbo/mapping/{interface} 节点获取DubboService的提供方应用名称。并且新建一个ServiceDiscoveryRegistry$DefaultMappingListener类型的监听器监听该节点的数据变动(该监听器会调用ServiceDiscoveryRegistry.subscribeURLs()同步最新的provider列表)。

2.获取应用实例列表
调用ZookeeperServiceDiscovery.getInstances()方法访问zookeeper注册中心的/services/{application}路径下的子节点,将子节点的数据解析成ServiceInstance对象包含实例的ip端口以及metadata信息,并封装到ServiceInstancsChangedEvent对象做为SericeInstancesChangedListener.onEvent()方法的入参,进入InstanceAddressURL的拼装过程。

3.获取应用实例的元数据,拼接InstanceAddressURL
调用ZookeeperMetadataReport.getAppMetadata()从/dubbo/metadata/{application}/{metadataRevision} 获取应用实例的元数据;有几个不同metadataRevision就调用几次,直到所有的medataRevision版本的元数据都获取到;拼装InstanceAddressURL。

4.将InstanceAddressURL转换成Invoker
在调用NotifyListener之前会先执行推空保护的逻辑。
最后再是调用ServiceDiscoveryRegistryDirectory.notify()方法将URL转换成Invoker,并且更新Invokers,同时对比原来缓存的Invokers,在新的Invokers中不再存在的Invoker会执行destroy方法进行销毁。

5.监听应用实例变更
完成服务发现逻辑后,调用ZookeeperServiceDiscovery.addServiceInstancesChangedListener()方法将ServiceInstancesChangedListener对象做为监听器watch 注册中心/services/{application}下的子节点,监听实例变动,更新providers实例列表。

实例级服务发现时序图:
在这里插入图片描述

local模式的实例级服务注册发现

local模式和remote模式的区别仅是在于应用服务实例的元数据的获取方式不同。

local 模式

local模式下provider会在启动阶段调用ConfigurableMetadataServiceExporter.export()来暴露一个MetadataService接口,引用的类是InMemoryWritableMetadataService,供consumer以直连的方式获取本实例的应用元数据。

consumer会在ServiceInstancesChangedListener.doGetMetadataInfo()方法中通过MetadataUtils.getMetadataServiceProxy()方法创建一个MetadataService的dubbo代理类,然后直接调用该代理的getMetadataInfo()方法直接向provider实例获取应用元数据;获取到之后再销毁该该代理类。

remote模式

remote模式下provider会在ServiceinstanceMetadataUtils.reportMetadataToRemote()方法中调用RemoteMetadataServiceImpl.publishMetadata()方法往元数据中心写应用实例的元数据。
consumer会在ServiceInstancesChangedListener.doGetMetadataInfo()方法中调用RemoteMetadataServiceImpl.getMetadata()方法从元数据中心读取应用实例的元数据。

引用参考

Apache-Dubbo-服务自省架构设计

猜你喜欢

转载自blog.csdn.net/Mr_rain/article/details/125341435