【高性能网关soul学习】14. 插件之dubbo原理
本文目标:
- 介绍 dubbo 插件原理,本文主要以 alibaba-dubbo 部分作为介绍
dubbo 插件
dubbo 插件作为插件链的一环,处理 dubbo 的请求
我们启动相关服务,然后跟踪请求分析逻辑代码做了些什么
AlibabaDubboPlugin 相关的核心大致流程图:
- doExecute:异常情况检查
- alibabaDubboProxyService.genericInvoker
- 根据 metaData的信息去缓存ApplicationConfigCache 获取或者创建一个 ReferenceConfig
- 从ReferenceConfig 中获取一个 GenericService
- ReferenceConfig 实例很重,封装了与注册中心的连接以及与提供者的连接
- dubboParamResolveService.buildParameter :构建请求参数
- genericService.$invoke:调用结果返回
- alibabaDubboProxyService.genericInvoker
- DubboResponsePlugin: 对结果进行处理,封装为webflux的结果进行返回
- WebFluxResultUtils.result
@Override
protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
String body = exchange.getAttribute(Constants.DUBBO_PARAMS);
SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
assert soulContext != null;
MetaData metaData = exchange.getAttribute(Constants.META_DATA);
if (!checkMetaData(metaData)) {
// return 异常处理
}
if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && StringUtils.isBlank(body)) {
// return 异常处理
}
Object result = alibabaDubboProxyService.genericInvoker(body, metaData);
if (Objects.nonNull(result)) {
exchange.getAttributes().put(Constants.DUBBO_RPC_RESULT, result);
} else {
exchange.getAttributes().put(Constants.DUBBO_RPC_RESULT, Constants.DUBBO_RPC_RESULT_EMPTY);
}
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
return chain.execute(exchange);
}
public Object genericInvoker(final String body, final MetaData metaData) throws SoulException {
// 获取或者传建一个服务引用配置 ReferenceConfig
ReferenceConfig<GenericService> reference = ApplicationConfigCache.getInstance().get(metaData.getPath());
if (Objects.isNull(reference) || StringUtils.isEmpty(reference.getInterface())) {
ApplicationConfigCache.getInstance().invalidate(metaData.getPath());
reference = ApplicationConfigCache.getInstance().initRef(metaData);
}
// 从引用配置中获取一个泛化服务
GenericService genericService = reference.get();
try {
Pair<String[], Object[]> pair;
// 构建请求参数
if (ParamCheckUtils.dubboBodyIsEmpty(body)) {
pair = new ImmutablePair<>(new String[]{}, new Object[]{});
} else {
pair = dubboParamResolveService.buildParameter(body, metaData.getParameterTypes());
}
// 请求并返回
return genericService.$invoke(metaData.getMethodName(), pair.getLeft(), pair.getRight());
} catch (GenericException e) {
log.error("dubbo invoker have exception", e);
throw new SoulException(e.getExceptionMessage());
}
}
总结
- 介绍了 soul 中 dubbo 的调用流程,可以发现实现所用的逻辑还是比较清晰简单的