1. 程式人生 > 其它 >【高效能閘道器soul學習】14. 外掛之dubbo原理

【高效能閘道器soul學習】14. 外掛之dubbo原理

技術標籤:Soul閘道器javadubbo

【高效能閘道器soul學習】14. 外掛之dubbo原理

本文目標:

  1. 介紹 dubbo 外掛原理,本文主要以 alibaba-dubbo 部分作為介紹

dubbo 外掛

dubbo 外掛作為外掛鏈的一環,處理 dubbo 的請求
我們啟動相關服務,然後跟蹤請求分析邏輯程式碼做了些什麼

AlibabaDubboPlugin 相關的核心大致流程圖:

  1. doExecute:異常情況檢查
    1. alibabaDubboProxyService.genericInvoker
      1. 根據 metaData的資訊去快取ApplicationConfigCache 獲取或者建立一個 ReferenceConfig
      2. 從ReferenceConfig 中獲取一個 GenericService
        1. ReferenceConfig 例項很重,封裝了與註冊中心的連線以及與提供者的連線
      3. dubboParamResolveService.buildParameter :構建請求引數
      4. genericService.$invoke:呼叫結果返回
  2. DubboResponsePlugin: 對結果進行處理,封裝為webflux的結果進行返回
    1. WebFluxResultUtils.result
otherPlugin AlibabaDubboPlugin AlibabaDubboProxyService
ApplicationConfigCache dubboParamResolveService dubbo服務 doExecute genericInvoker 獲取或請求建立ReferenceConfig 返回ReferenceConfig<GenericService> 構建請求引數 泛化呼叫 泛化呼叫呼叫結果返回 otherPlugin AlibabaDubboPlugin AlibabaDubboProxyService
ApplicationConfigCache dubboParamResolveService dubbo服務
@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 的呼叫流程,可以發現實現所用的邏輯還是比較清晰簡單的