【Soul源碼閱讀-04】sofa插件初體驗

目標

  • 運行examples下面的 sofa-rpc 服務
  • 學習文檔,結合 sofa 插件,發起 http 請求 soul 網關,體驗 sofa 代理

soul 網關接入 sofa 應用

  • 參考官方文檔:https://dromara.org/zh-cn/doc...html

    • 引入相關依賴java

      soul-bootstrap新增以下依賴:spring

      <dependency>
                 <groupId>com.alipay.sofa</groupId>
                 <artifactId>sofa-rpc-all</artifactId>
                 <version>5.7.6</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.curator</groupId>
                 <artifactId>curator-client</artifactId>
                 <version>4.0.1</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.curator</groupId>
                 <artifactId>curator-framework</artifactId>
                 <version>4.0.1</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.curator</groupId>
                 <artifactId>curator-recipes</artifactId>
                 <version>4.0.1</version>
             </dependency>
             <dependency>
                 <groupId>org.dromara</groupId>
                 <artifactId>soul-spring-boot-starter-plugin-sofa</artifactId>
                 <version>2.2.1</version>
             </dependency>

      soul-examples-sofa新增以下依賴:apache

      <dependency>
            <groupId>org.dromara</groupId>
                  <artifactId>soul-spring-boot-starter-client-sofa</artifactId>
                  <version>2.2.1</version>
                  <exclusions>
                      <exclusion>
                          <artifactId>guava</artifactId>
                          <groupId>com.google.guava</groupId>
                      </exclusion>
                  </exclusions>
              </dependency>
    • application.yml添加相關配置json

      soul:
        sofa:
          adminUrl: http://localhost:9095
          contextPath: /sofa
          appName: sofa
            # adminUrl: 爲你啓動的 soul-admin 項目的ip + 端口,注意要加 http://
            # contextPath: 爲你的這個項目在soul網關的路由前綴,好比/order ,/product 等等,網關會根據你的這個前 綴來進行路由.
            # appName:你的應用名稱,不配置的話,會默認取 sofa 配置中application 中的名稱
  • sofa 插件設置

    soul-admin 插件管理中,sofa 插件設置爲開啓
    image-20210118210643bootstrap

    sofa 插件中配置你的註冊地址
    image-20210118210715api

  • 接口註冊到網關app

    • sofa 服務實現類的方法上加上 @SoulSofaClient 註解,表示該接口方法註冊到網關
  • 先啓動zk,而後再啓動TestSofaApplication,輸出日誌 init sofa client reference success,表示sofa接口已經發布到 soul 網關
    image-20210118210828

sofa 用戶請求以及參數說明

sofa 參數傳遞方式:spring-boot

  • 經過 http post 方式訪問網關,經過body,json類型傳遞
  • 單個java bean參數類型 (默認)
  • 自定義實現多參數支持:post

    • 在你搭建的網關項目中,新增一個類 A,實現 org.dromara.soul.plugin.api.sofa.SofaParamResolveService

      public interface SofaParamResolveService {
             /**
              * Build parameter pair.
              * this is Resolve http body to get sofa param.
              *
              * @param body           http中body傳的json字符串 
              * @param parameterTypes 匹配到的方法參數類型列表,若是有多個,則使用,分割
              * @return pair left爲參數類型,right爲參數值
              */
             Pair<String[], Object[]> buildParameter(String body, String parameterTypes);
         }
  • 經過 http post 方式訪問網關,經過body,json類型傳遞
  • image-20210118212122

使用 http post 方式訪問,後臺NullPointerException
image-20210118212251

打斷點,調試

GenericService genericService = reference.refer();
        Pair<String[], Object[]> pair;
        if (null == body || "".equals(body) || "{}".equals(body) || "null".equals(body)) {
            pair = new ImmutablePair<>(new String[]{}, new Object[]{});
        } else {
            // body 不爲空
            pair = sofaParamResolveService.buildParameter(body, metaData.getParameterTypes());
        }

body 不爲空時,調用了sofaParamResolveService.buildParameter(String body, String parameterTypes)方法,但在官方介紹中,只有自定義實現多參數支持才須要實現org.dromara.soul.plugin.api.sofa.SofaParamResolveService類,不知道這塊是否是個BUG。代碼中搜了搜,發現只在SofaProxyServiceTest類中以靜態內部類方式實現了`sofaParamResolveService

image-20210118214106

先實現下`sofaParamResolveService試下結果

public Pair<String[], Object[]> buildParameter(final String body, final String parameterTypes) {
        Map<String, Object> paramMap = GsonUtils.getInstance().toObjectMap(body);
        String[] parameter = StringUtils.split(parameterTypes, ",");
        if (parameter.length == 1 && !isBaseType(parameter[0])) {
            for (String key : paramMap.keySet()) {
                Object obj = paramMap.get(key);
                if (obj instanceof JsonObject) {
                    paramMap.put(key, GsonUtils.getInstance().convertToMap(obj.toString()));
                } else if (obj instanceof JsonArray) {
                    paramMap.put(key, GsonUtils.getInstance().fromList(obj.toString(), Object.class));
                } else {
                    paramMap.put(key, obj);
                }
            }
            return new ImmutablePair<>(parameter, new Object[]{paramMap});
        }
        List<Object> list = new LinkedList<>();
        for (String key : paramMap.keySet()) {
            Object obj = paramMap.get(key);
            if (obj instanceof JsonObject) {
                list.add(GsonUtils.getInstance().convertToMap(obj.toString()));
            } else if (obj instanceof JsonArray) {
                list.add(GsonUtils.getInstance().fromList(obj.toString(), Object.class));
            } else {
                list.add(obj);
            }
        }
        Object[] objects = list.toArray();
        return new ImmutablePair<>(parameter, objects);
    }

    private boolean isBaseType(final String paramType) {
        return paramType.startsWith("java") || paramType.startsWith("[Ljava");
    }

再次運行,成功:
image-20210118215803

主要了解了一下 soul 網關接入 Sofa 應用,使用各類請求參數經過 http 請求 soul 網關,體驗 sofa 代理。

相關文章
相關標籤/搜索