You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/06/27 03:50:34 UTC

[skywalking] branch perf/als created (now 7490b03)

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

kezhenxu94 pushed a change to branch perf/als
in repository https://gitbox.apache.org/repos/asf/skywalking.git.


      at 7490b03  Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS)

This branch includes the following new commits:

     new 7490b03  Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[skywalking] 01/01: Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS)

Posted by ke...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kezhenxu94 pushed a commit to branch perf/als
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 7490b0304f539660fbe57752e01cc09393e30f37
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Sun Jun 27 11:49:54 2021 +0800

    Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS)
---
 CHANGES.md                                         |  1 +
 .../receiver/envoy/ServiceMetaInfoFactoryImpl.java |  2 +-
 .../server/receiver/envoy/als/mx/FieldsHelper.java | 53 +++++++++++++++-------
 .../envoy/als/mx/ServiceMetaInfoAdapter.java       |  3 +-
 4 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index dae2bc0..5956f91 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -43,6 +43,7 @@ Release Notes.
 * OAL supports generating metrics from events.
 * Support endpoint name grouping by OpenAPI definitions.
 * Fix CounterWindow increase computing issue.
+* Performance: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS).
 
 #### UI
 * Fix the date component for log conditions.
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/ServiceMetaInfoFactoryImpl.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/ServiceMetaInfoFactoryImpl.java
index 516989c..7916e01 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/ServiceMetaInfoFactoryImpl.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/ServiceMetaInfoFactoryImpl.java
@@ -36,7 +36,7 @@ public class ServiceMetaInfoFactoryImpl implements ServiceMetaInfoFactory {
     }
 
     @Override
-    public ServiceMetaInfo fromStruct(final Struct struct) throws Exception {
+    public ServiceMetaInfo fromStruct(final Struct struct) {
         return new ServiceMetaInfoAdapter(struct);
     }
 }
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
index a615284..48ad1d3 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/FieldsHelper.java
@@ -18,28 +18,36 @@
 
 package org.apache.skywalking.oap.server.receiver.envoy.als.mx;
 
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.protobuf.Struct;
-import com.google.protobuf.Value;
 import java.io.InputStream;
-import java.lang.reflect.Method;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.BiConsumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import lombok.RequiredArgsConstructor;
-import lombok.experimental.Delegate;
-import lombok.extern.slf4j.Slf4j;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.skywalking.oap.server.library.module.ModuleStartException;
 import org.apache.skywalking.oap.server.library.util.ResourceUtils;
 import org.apache.skywalking.oap.server.receiver.envoy.als.ServiceMetaInfo;
 import org.yaml.snakeyaml.Yaml;
 
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.protobuf.Struct;
+import com.google.protobuf.Value;
+
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.Delegate;
+import lombok.extern.slf4j.Slf4j;
+
 @Slf4j
 public enum FieldsHelper {
     SINGLETON;
@@ -54,7 +62,7 @@ public enum FieldsHelper {
     /**
      * The mappings from the field name of {@link ServiceMetaInfo} to its {@code setter}.
      */
-    private Map<String, Method> fieldSetterMapping;
+    private Map<String, BiConsumer<? super ServiceMetaInfo, String>> fieldSetterMapping;
 
     public void init(final String file,
                      final Class<? extends ServiceMetaInfo> serviceInfoClass) throws Exception {
@@ -69,7 +77,7 @@ public enum FieldsHelper {
         }
 
         final Yaml yaml = new Yaml();
-        final Map<String, String> config = (Map<String, String>) yaml.load(inputStream);
+        final Map<String, String> config = yaml.load(inputStream);
 
         fieldNameMapping = new HashMap<>(config.size());
         fieldSetterMapping = new HashMap<>(config.size());
@@ -114,10 +122,22 @@ public enum FieldsHelper {
             );
 
             try {
-                final Method setterMethod = serviceInfoClass.getMethod("set" + StringUtils.capitalize(serviceMetaInfoFieldName), String.class);
-                setterMethod.setAccessible(true);
-                fieldSetterMapping.put(serviceMetaInfoFieldName, setterMethod);
-            } catch (final NoSuchMethodException e) {
+                final String setter = "set" + StringUtils.capitalize(serviceMetaInfoFieldName);
+                final MethodHandles.Lookup caller = MethodHandles.lookup();
+                final Class<?> parameterType = String.class;
+                final CallSite site = LambdaMetafactory.metafactory(
+                        caller, "accept",
+                        MethodType.methodType(BiConsumer.class),
+                        MethodType.methodType(void.class, serviceInfoClass, parameterType),
+                        caller.findVirtual(
+                                serviceInfoClass, setter,
+                                MethodType.methodType(void.class, parameterType)),
+                        MethodType.methodType(void.class, serviceInfoClass, parameterType));
+                final MethodHandle factory = site.getTarget();
+                final BiConsumer<? super ServiceMetaInfo, String> method =
+                        (BiConsumer<? super ServiceMetaInfo, String>) factory.invoke();
+                fieldSetterMapping.put(serviceMetaInfoFieldName, method);
+            } catch (final Throwable e) {
                 throw new ModuleStartException("Initialize method error", e);
             }
         }
@@ -129,9 +149,8 @@ public enum FieldsHelper {
      *
      * @param metadata        the {@link Struct} metadata from where to retrieve and inflate the {@code serviceMetaInfo}.
      * @param serviceMetaInfo the {@code serviceMetaInfo} to be inflated.
-     * @throws Exception if failed to inflate the {@code serviceMetaInfo}
      */
-    public void inflate(final Struct metadata, final ServiceMetaInfo serviceMetaInfo) throws Exception {
+    public void inflate(final Struct metadata, final ServiceMetaInfo serviceMetaInfo) {
         final Value empty = Value.newBuilder().setStringValue("-").build();
         final Value root = Value.newBuilder().setStructValue(metadata).build();
         for (final Map.Entry<String, ServiceNameFormat> entry : fieldNameMapping.entrySet()) {
@@ -153,7 +172,7 @@ public enum FieldsHelper {
             }
             final String value = Strings.lenientFormat(serviceNameFormat.format, values);
             if (!Strings.isNullOrEmpty(value)) {
-                fieldSetterMapping.get(entry.getKey()).invoke(serviceMetaInfo, value);
+                fieldSetterMapping.get(entry.getKey()).accept(serviceMetaInfo, value);
             }
         }
     }
diff --git a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/ServiceMetaInfoAdapter.java b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/ServiceMetaInfoAdapter.java
index df8e38b..49ba821 100644
--- a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/ServiceMetaInfoAdapter.java
+++ b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/als/mx/ServiceMetaInfoAdapter.java
@@ -121,9 +121,8 @@ public class ServiceMetaInfoAdapter extends ServiceMetaInfo {
      * The same functionality with {@link ServiceMetaInfoAdapter#ServiceMetaInfoAdapter(com.google.protobuf.ByteString)}.
      *
      * @param metadata the {@link Struct struct} to adapt from.
-     * @throws Exception if the {@link Struct struct} can not be adapted to a {@link ServiceMetaInfo}.
      */
-    public ServiceMetaInfoAdapter(final Struct metadata) throws Exception {
+    public ServiceMetaInfoAdapter(final Struct metadata) {
         FieldsHelper.SINGLETON.inflate(requireNonNull(metadata), this);
     }