This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 5d8ebe62f [SCB-2813]first time invoke performance tuning (#4052)
5d8ebe62f is described below

commit 5d8ebe62fa30eb09282974ac1a2d94160c0741fe
Author: liubao68 <[email protected]>
AuthorDate: Wed Nov 22 17:28:56 2023 +0800

    [SCB-2813]first time invoke performance tuning (#4052)
---
 .../rest/codec/param/BodyProcessorCreator.java     |  2 +-
 .../servicecomb/core/filter/AbstractFilter.java    |  2 +-
 .../apache/servicecomb/core/filter/FilterNode.java |  8 ++--
 .../core/filter/impl/ParameterValidatorFilter.java | 44 ++++++++++++++++++++--
 .../core/invocation/InvocationStageTrace.java      |  2 +-
 .../servicecomb/registry/DiscoveryManager.java     |  3 +-
 .../discovery/StatefulDiscoveryInstance.java       |  2 +-
 .../foundation/vertx/stream/BufferInputStream.java | 13 ++++---
 .../metrics/core/publish/SlowInvocationLogger.java | 37 +++++++++---------
 .../basic/integration/InstanceOpenAPIRegistry.java |  3 +-
 10 files changed, 80 insertions(+), 36 deletions(-)

diff --git 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index f33e0bade..78d171121 100644
--- 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++ 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -249,7 +249,7 @@ public class BodyProcessorCreator implements 
ParamValueProcessorCreator<RequestB
     }
 
     /**
-     * Deserialize body object into body buffer, according to the Content-Type.
+     * Serialize body object into body buffer, according to the Content-Type.
      */
     private Buffer createBodyBuffer(String contentType, Object arg) throws 
IOException {
       if (SwaggerConst.PROTOBUF_TYPE.equals(contentType)) {
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/filter/AbstractFilter.java 
b/core/src/main/java/org/apache/servicecomb/core/filter/AbstractFilter.java
index 35a01c251..17d555fc8 100644
--- a/core/src/main/java/org/apache/servicecomb/core/filter/AbstractFilter.java
+++ b/core/src/main/java/org/apache/servicecomb/core/filter/AbstractFilter.java
@@ -56,7 +56,7 @@ public abstract class AbstractFilter implements Filter, 
EnvironmentAware {
   @Override
   public String getNameWithOrder() {
     if (nameWithOrder == null) {
-      nameWithOrder = getName() + "(" + getOrder() + ")";
+      nameWithOrder = String.format("F(%1$06d)-%2$s", getOrder(), getName());
     }
     return nameWithOrder;
   }
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java 
b/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java
index 907ffe82d..b589730f7 100644
--- a/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java
+++ b/core/src/main/java/org/apache/servicecomb/core/filter/FilterNode.java
@@ -62,15 +62,15 @@ public class FilterNode {
   }
 
   public CompletableFuture<Response> onFilter(Invocation invocation) {
-    
invocation.getInvocationStageTrace().recordStageBegin(this.filter.getNameWithOrder());
-    // When transport name is empty, maybe edge and transport filters need to 
be executed.
-    // And we can't set Endpoint before load balance in edge.
+    // When transport name is empty, maybe edge transport filters need to be 
executed.
+    // Can't set Endpoint before load balance in edge.
     if (invocation.getTransportName() != null && 
!filter.enabledForTransport(invocation.getTransportName())) {
       return nextNode.onFilter(invocation);
     }
 
+    String stage = 
invocation.getInvocationStageTrace().recordStageBegin(this.filter.getNameWithOrder());
     return AsyncUtils.tryCatchSupplierFuture(() -> filter.onFilter(invocation, 
nextNode)
-            .whenComplete((r, e) -> 
invocation.getInvocationStageTrace().recordStageEnd(this.filter.getNameWithOrder())))
+            .whenComplete((r, e) -> 
invocation.getInvocationStageTrace().recordStageEnd(stage)))
         .thenApply(this::rethrowExceptionInResponse);
   }
 
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java
 
b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java
index ccc5f043f..c33c79579 100644
--- 
a/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java
+++ 
b/core/src/main/java/org/apache/servicecomb/core/filter/impl/ParameterValidatorFilter.java
@@ -38,12 +38,35 @@ import org.springframework.beans.factory.InitializingBean;
 
 import jakarta.validation.ConstraintViolation;
 import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Valid;
 import jakarta.validation.Validation;
 import jakarta.validation.ValidatorFactory;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotNull;
 import jakarta.validation.executable.ExecutableValidator;
 import jakarta.validation.groups.Default;
 
 public class ParameterValidatorFilter extends AbstractFilter implements 
ProviderFilter, InitializingBean {
+  private static class Service {
+    @SuppressWarnings("unused")
+    public void service(@Valid Model model) {
+
+    }
+  }
+
+  private static class Model {
+    @NotNull
+    String name;
+
+    @Min(10)
+    int age;
+
+    Model(String name, int age) {
+      this.name = name;
+      this.age = age;
+    }
+  }
+
   private static final Logger LOGGER = 
LoggerFactory.getLogger(ParameterValidatorFilter.class);
 
   public static final String NAME = "validator";
@@ -66,6 +89,21 @@ public class ParameterValidatorFilter extends AbstractFilter 
implements Provider
   public void afterPropertiesSet() {
     validator = createValidatorFactory()
         .getValidator().forExecutables();
+    initValidate();
+  }
+
+  private void initValidate() {
+    // This method is intended to make first rpc call faster
+    // Because validation cache bean class, this way only make first rpc call 
a little faster.
+    try {
+      Model model = new Model("foo", 23);
+      Service instance = new Service();
+      Method method = Service.class.getMethod("service", Model.class);
+      Object[] args = new Object[] {model};
+      validator.validateParameters(instance, method, args, Default.class);
+    } catch (Throwable e) {
+      throw new IllegalStateException(e);
+    }
   }
 
   protected ValidatorFactory createValidatorFactory() {
@@ -100,9 +138,7 @@ public class ParameterValidatorFilter extends 
AbstractFilter implements Provider
 
   protected Set<ConstraintViolation<Object>> doValidate(Invocation invocation) 
{
     SwaggerProducerOperation producerOperation = 
invocation.getOperationMeta().getSwaggerProducerOperation();
-    Object instance = producerOperation.getProducerInstance();
-    Method method = producerOperation.getProducerMethod();
-    Object[] args = invocation.toProducerArguments();
-    return validator.validateParameters(instance, method, args, Default.class);
+    return 
validator.validateParameters(producerOperation.getProducerInstance(), 
producerOperation.getProducerMethod(),
+        invocation.toProducerArguments(), Default.class);
   }
 }
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
 
b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
index 0c28b99d0..f9d0166a4 100644
--- 
a/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
+++ 
b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
@@ -162,7 +162,7 @@ public class InvocationStageTrace {
 
   public String recordStageBegin(String stageName) {
     String realStageName = stageName;
-    if (stages.get(stageName) != null) {
+    while (stages.get(realStageName) != null) {
       realStageName = realStageName + "@";
     }
     Stage stage = new Stage();
diff --git 
a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
 
b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
index 4025e6f12..ff51504d7 100644
--- 
a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
+++ 
b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/DiscoveryManager.java
@@ -87,6 +87,7 @@ public class DiscoveryManager implements LifeCycle {
         }
       };
       thread.setPriority(Thread.MIN_PRIORITY);
+      thread.setDaemon(true);
       return thread;
     });
   }
@@ -104,7 +105,7 @@ public class DiscoveryManager implements LifeCycle {
             changed = true;
           }
           // check ping status
-          if (System.currentTimeMillis() - instance.getPingTime() > 180_000L) {
+          if (System.currentTimeMillis() - instance.getPingTime() > 60_000L) {
             boolean pingResult = ping.ping(instance);
             if (pingResult && instance.getPingStatus() != PingStatus.OK) {
               instance.setPingStatus(PingStatus.OK);
diff --git 
a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java
 
b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java
index fbcb16143..f06ea936d 100644
--- 
a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java
+++ 
b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/discovery/StatefulDiscoveryInstance.java
@@ -56,7 +56,7 @@ public class StatefulDiscoveryInstance extends 
AbstractDiscoveryInstance {
 
   private PingStatus pingStatus = PingStatus.UNKNOWN;
 
-  private long pingTime = 0;
+  private long pingTime = System.currentTimeMillis();
 
   private HistoryStatus historyStatus = HistoryStatus.CURRENT;
 
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferInputStream.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferInputStream.java
index 9eede6180..09840be11 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferInputStream.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/stream/BufferInputStream.java
@@ -20,11 +20,10 @@ package org.apache.servicecomb.foundation.vertx.stream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 
+import io.netty.buffer.ByteBuf;
 import jakarta.servlet.ReadListener;
 import jakarta.servlet.ServletInputStream;
 
-import io.netty.buffer.ByteBuf;
-
 public class BufferInputStream extends ServletInputStream {
   private final ByteBuf byteBuf;
 
@@ -83,12 +82,16 @@ public class BufferInputStream extends ServletInputStream {
   @Override
   public int read(byte[] b, int off, int len) {
     int avail = available();
-    if (len > avail) {
-      len = avail;
+    if (avail <= 0) {
+      return -1;
     }
 
     if (len == 0) {
-      return -1;
+      return 0;
+    }
+
+    if (len > avail) {
+      len = avail;
     }
 
     byteBuf.readBytes(b, off, len);
diff --git 
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
 
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
index b0417b239..8dc61ca8e 100644
--- 
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
+++ 
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
@@ -29,7 +29,8 @@ import static 
org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_
 import static 
org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_PROVIDER_SEND;
 import static 
org.apache.servicecomb.core.invocation.InvocationStageTrace.STAGE_TOTAL;
 
-import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.servicecomb.common.rest.RestConst;
@@ -40,7 +41,6 @@ import org.apache.servicecomb.core.SCBEngine;
 import org.apache.servicecomb.core.definition.OperationConfig;
 import org.apache.servicecomb.core.event.InvocationFinishEvent;
 import org.apache.servicecomb.core.invocation.InvocationStageTrace;
-import org.apache.servicecomb.core.invocation.InvocationStageTrace.Stage;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.slf4j.Logger;
@@ -114,11 +114,12 @@ public class SlowInvocationLogger {
         .append(formatPair("    ", STAGE_PROVIDER_ENCODE_RESPONSE, 
stageTrace.calcProviderEncodeResponse()))
         .append(formatPair("    ", STAGE_PROVIDER_SEND, 
stageTrace.calcProviderSendResponse()));
 
-    for (Entry<String, Stage> stage : stageTrace.getStages().entrySet()) {
-      sb.append(formatPair("    ", "Filter-" + stage.getKey(),
-          InvocationStageTrace.calc(stage.getValue().getEndTime(),
-              stage.getValue().getBeginTime())));
-    }
+    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());
+    sorted.stream().sorted().forEach(key -> {
+      sb.append(formatPair("    ", key,
+          
InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),
+              stageTrace.getStages().get(key).getBeginTime())));
+    });
 
     LOGGER.warn(sb.toString());
   }
@@ -150,11 +151,12 @@ public class SlowInvocationLogger {
         .append(formatPair("    ", STAGE_CONSUMER_WAIT, stageTrace.calcWait()))
         .append(formatPair("    ", STAGE_CONSUMER_DECODE_RESPONSE, 
stageTrace.calcConsumerDecodeResponse()));
 
-    for (Entry<String, Stage> stage : stageTrace.getStages().entrySet()) {
-      sb.append(formatPair("    ", "Filter-" + stage.getKey(),
-          InvocationStageTrace.calc(stage.getValue().getEndTime(),
-              stage.getValue().getBeginTime())));
-    }
+    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());
+    sorted.stream().sorted().forEach(key -> {
+      sb.append(formatPair("    ", key,
+          
InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),
+              stageTrace.getStages().get(key).getBeginTime())));
+    });
 
     LOGGER.warn(sb.toString());
   }
@@ -182,11 +184,12 @@ public class SlowInvocationLogger {
         .append(formatPair("    ", STAGE_PROVIDER_SEND, 
stageTrace.calcProviderSendResponse()))
     ;
 
-    for (Entry<String, Stage> stage : stageTrace.getStages().entrySet()) {
-      sb.append(formatPair("    ", "Filter-" + stage.getKey(),
-          InvocationStageTrace.calc(stage.getValue().getEndTime(),
-              stage.getValue().getBeginTime())));
-    }
+    List<String> sorted = new ArrayList<>(stageTrace.getStages().keySet());
+    sorted.stream().sorted().forEach(key -> {
+      sb.append(formatPair("    ", key,
+          
InvocationStageTrace.calc(stageTrace.getStages().get(key).getEndTime(),
+              stageTrace.getStages().get(key).getBeginTime())));
+    });
 
     LOGGER.warn(sb.toString());
   }
diff --git 
a/solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/InstanceOpenAPIRegistry.java
 
b/solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/InstanceOpenAPIRegistry.java
index b2fd237a9..f8314d5af 100644
--- 
a/solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/InstanceOpenAPIRegistry.java
+++ 
b/solutions/solution-basic/src/main/java/org/apache/servicecomb/solution/basic/integration/InstanceOpenAPIRegistry.java
@@ -84,7 +84,8 @@ public class InstanceOpenAPIRegistry implements 
OpenAPIRegistry {
   @SuppressWarnings("unchecked")
   public Map<String, OpenAPI> loadOpenAPI(String application, String 
serviceName) {
     List<? extends DiscoveryInstance> discoveryInstances =
-        discoveryManager.findServiceInstances(application, serviceName);
+        discoveryManager.getOrCreateVersionedCache(application, 
serviceName).data();
+
     if (discoveryInstances.isEmpty()) {
       throw new InvocationException(Status.INTERNAL_SERVER_ERROR, "no 
instances");
     }

Reply via email to