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 09:57:15 UTC
[skywalking] branch master updated: Perf: optimize Envoy ALS
analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k
RPS) (#7182)
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new e7bc81a Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS) (#7182)
e7bc81a is described below
commit e7bc81abbbcfdb32263f28b5eab1263414687489
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Sun Jun 27 17:56:59 2021 +0800
Perf: optimize Envoy ALS analyzer performance in high traffic load scenario (reduce ~1cpu in ~10k RPS) (#7182)
---
CHANGES.md | 1 +
.../receiver/envoy/ServiceMetaInfoFactoryImpl.java | 2 +-
.../server/receiver/envoy/als/mx/FieldsHelper.java | 52 +++++++++++++++-------
.../envoy/als/mx/ServiceMetaInfoAdapter.java | 3 +-
4 files changed, 38 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..e0da74c 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,21 @@ 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 lookup = MethodHandles.lookup();
+ final Class<?> parameterType = String.class;
+ final CallSite site = LambdaMetafactory.metafactory(
+ lookup, "accept",
+ MethodType.methodType(BiConsumer.class),
+ MethodType.methodType(void.class, Object.class, Object.class),
+ lookup.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 +148,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 +171,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);
}