You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by GitBox <gi...@apache.org> on 2022/04/01 12:44:52 UTC

[GitHub] [incubator-shenyu] dragon-zhang opened a new issue #3171: [Question] performance problem in `MotanProxyService`

dragon-zhang opened a new issue #3171:
URL: https://github.com/apache/incubator-shenyu/issues/3171


   ### Question
   
   In `org.apache.shenyu.plugin.motan.proxy.MotanProxyService#genericInvoker`, we have a performance problem :
   ```java
       public Mono<Object> genericInvoker(final String body, final MetaData metaData, final ServerWebExchange exchange) throws ShenyuException {
           Map<String, Map<String, String>> rpcContext = exchange.getAttribute(Constants.GENERAL_CONTEXT);
           Optional.ofNullable(rpcContext).map(context -> context.get(PluginEnum.MOTAN.getName())).ifPresent(context -> {
               context.forEach((k, v) -> RpcContext.getContext().setRpcAttachment(k, v));
           });
           RefererConfig<CommonHandler> reference = ApplicationConfigCache.getInstance().get(metaData.getPath());
           if (Objects.isNull(reference) || StringUtils.isEmpty(reference.getServiceInterface())) {
               ApplicationConfigCache.getInstance().invalidate(metaData.getPath());
               reference = ApplicationConfigCache.getInstance().initRef(metaData);
           }
           CommonHandler commonHandler = reference.getRef();
           ApplicationConfigCache.MotanParamInfo motanParamInfo = ApplicationConfigCache.PARAM_MAP.get(metaData.getMethodName());
           Object[] params;
           if (Objects.isNull(motanParamInfo)) {
               params = new Object[0];
           } else {
               int num = motanParamInfo.getParamTypes().length;
               params = new Object[num];
               Map<String, Object> bodyMap = GsonUtils.getInstance().convertToMap(body);
               for (int i = 0; i < num; i++) {
                   params[i] = bodyMap.get(motanParamInfo.getParamNames()[i]).toString();
               }
           }
           ResponseFuture responseFuture;
           //CHECKSTYLE:OFF IllegalCatch
           try {
               responseFuture = (ResponseFuture) commonHandler.asyncCall(metaData.getMethodName(), params, Object.class);
           } catch (Throwable e) {
               LOG.error("Exception caught in MotanProxyService#genericInvoker.", e);
               return null;
           }
           //CHECKSTYLE:ON IllegalCatch
           ResponseFuture finalResponseFuture = responseFuture;
   //fixme If there are many time-consuming tasks, the ForkJoinPool with only a few threads will become a performance bottleneck
           CompletableFuture<Object> future = CompletableFuture.supplyAsync(finalResponseFuture::getValue);
           return Mono.fromFuture(future.thenApply(ret -> {
               if (Objects.isNull(ret)) {
                   ret = Constants.MOTAN_RPC_RESULT_EMPTY;
               }
               exchange.getAttributes().put(Constants.RPC_RESULT, ret);
               exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
               return ret;
           })).onErrorMap(ShenyuException::new);
       }
   ```
   so I'm going to adjust the thread pool to `cached`:
   ```java
       private final ExecutorService threadPool = Executors.newCachedThreadPool(ShenyuThreadFactory.create("shenyu-motan", true));
   
       public Mono<Object> genericInvoker(final String body, final MetaData metaData, final ServerWebExchange exchange) throws ShenyuException {
           //......
           CompletableFuture<Object> future = CompletableFuture.supplyAsync(finalResponseFuture::getValue, threadPool);
           return Mono.fromFuture(future.thenApply(ret -> {
               if (Objects.isNull(ret)) {
                   ret = Constants.MOTAN_RPC_RESULT_EMPTY;
               }
               exchange.getAttributes().put(Constants.RPC_RESULT, ret);
               exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
               return ret;
           })).onErrorMap(ShenyuException::new);
       }
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shenyu.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org