soul网关学习8-dubbo协议转换3
2021-01-22 本文已影响0人
niuxin
继续上篇分析,这里只分析dubbo插件是如何处理配置数据的。
dubbo插件配置数据处理器
- 回到源码
org.dromara.soul.plugin.alibaba.dubbo.handler.AlibabaDubboPluginDataHandler
AlibabaDubboPluginDataHandler - 从上图可以看到
AlibabaDubboPluginDataHandler
只会处理plugin
的配置,对于selector
与rule
的配置是不进行进行任何处理的【需纠正一下:这里不是说selector
与rule
的配置对于dubbo插件来说是无意义的,只是AlibabaDubboPluginDataHandler
不处理。真正处理selector
与rule
的逻辑就是在CommonPluginDataSubscriber
的subscribeDataHandler
方法中完成的;因为对于不同插件其处理逻辑大致相同,因此只有极个别的插件需要重写handlerSelector
与handlerRule
方法】。那dubbo
插件中的配置是如何能被正确dubbo服务的请求路径给到soul-bootstrap
做路由的呢? - 我们知道dubbo服务注册时,会生成对应的元数据,于是点击元数据的同步,看下
bootstrap
会有什么反应
meta_data_sync - 元数据的配置在
soul-bootstrap
端的处理逻辑则由org.dromara.soul.plugin.sync.data.weboscket.handler.MetaDataHandler
决定
WebsocketDataHandler -
看下具体的处理逻辑是怎样的
MetaDataHandler - 我们先看看
MetaDataSubscriber
的类继承结构
MetaDataSubscriber-implements - 从上图基本可以看出对于每种特定的微服务框架都有一个handler与之对应,这里我们只关注
org.dromara.soul.plugin.alibaba.dubbo.subscriber.AlibabaDubboMetaDataSubscriber
。打断点进入发现,这里的处理大致如下:所有dubbo服务的接口,都会放到org.dromara.soul.plugin.alibaba.dubbo.cache.ApplicationConfigCache
的cache
中,key为dubbo服务声明的path,value则是根据元数据生成的服务引用ReferenceConfig
。届时在具体调用的时候,则能根据请求的url找到ReferenceConfig
,再根据其生成相应的Invoker
,从而完成http请求转换为dubbo服务的请求
public void onSubscribe(final MetaData metaData) {
// 只是把跟dubbo相关的元数据存放到内存中
if (RpcTypeEnum.DUBBO.getName().equals(metaData.getRpcType())) {
MetaData exist = META_DATA.get(metaData.getPath());
// 如果当前的dubbo路径不存在,则需要初始化服务引用
if (Objects.isNull(META_DATA.get(metaData.getPath())) || Objects.isNull(ApplicationConfigCache.getInstance().get(metaData.getPath()))) {
// The first initialization
// 将服务路径与服务引用配置放到应用配置缓存中
ApplicationConfigCache.getInstance().initRef(metaData);
} else {
// There are updates, which only support the update of four properties of serviceName rpcExt parameterTypes methodName,
// because these four properties will affect the call of Dubbo;
// 如果存在,则查看是否存在属性变更的地方,如果存在则要重新build的服务引用
if (!Objects.equals(metaData.getServiceName(), exist.getServiceName())
|| !Objects.equals(metaData.getRpcExt(), exist.getRpcExt())
|| !Objects.equals(metaData.getParameterTypes(), exist.getParameterTypes())
|| !Objects.equals(metaData.getMethodName(), exist.getMethodName())) {
// 重新构建服务引用并放到应用配置缓存中
ApplicationConfigCache.getInstance().build(metaData);
}
}
META_DATA.put(metaData.getPath(), metaData);
}
}
- 看下元数据
MetaData
生成引用服务配置ReferenceConfig
的逻辑
public ReferenceConfig<GenericService> build(final MetaData metaData) {
ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
reference.setGeneric(true);
reference.setApplication(applicationConfig);
reference.setRegistry(registryConfig);
reference.setInterface(metaData.getServiceName());
reference.setProtocol("dubbo");
String rpcExt = metaData.getRpcExt();
DubboParamExtInfo dubboParamExtInfo = GsonUtils.getInstance().fromJson(rpcExt, DubboParamExtInfo.class);
if (Objects.nonNull(dubboParamExtInfo)) {
// 版本
if (StringUtils.isNoneBlank(dubboParamExtInfo.getVersion())) {
reference.setVersion(dubboParamExtInfo.getVersion());
}
// 分组
if (StringUtils.isNoneBlank(dubboParamExtInfo.getGroup())) {
reference.setGroup(dubboParamExtInfo.getGroup());
}
// 负载均衡
if (StringUtils.isNoneBlank(dubboParamExtInfo.getLoadbalance())) {
final String loadBalance = dubboParamExtInfo.getLoadbalance();
reference.setLoadbalance(buildLoadBalanceName(loadBalance));
}
// url
if (StringUtils.isNoneBlank(dubboParamExtInfo.getUrl())) {
reference.setUrl(dubboParamExtInfo.getUrl());
}
// 超时
Optional.ofNullable(dubboParamExtInfo.getTimeout()).ifPresent(reference::setTimeout);
// 重试
Optional.ofNullable(dubboParamExtInfo.getRetries()).ifPresent(reference::setRetries);
}
try {
Object obj = reference.get();
if (obj != null) {
log.info("init alibaba dubbo reference success there meteData is :{}", metaData.toString());
// 将请求路径与dubbo服务引入放入应用配置的cache中
cache.put(metaData.getPath(), reference);
}
} catch (Exception e) {
log.error("init alibaba dubbo refernce ex:{}", e.getMessage());
}
return reference;
}