You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2020/02/04 05:40:36 UTC
[dubbo] branch master updated: [Dubbo-perf]: Reduce object
allocation for ProtocolUtils.serviceKey(int, String, String, String) (#5525)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/master by this push:
new c0d62ed [Dubbo-perf]: Reduce object allocation for ProtocolUtils.serviceKey(int, String, String, String) (#5525)
c0d62ed is described below
commit c0d62ed7a83347fa469c2b2a7d75287a5feb799b
Author: LinShunKang <li...@gmail.com>
AuthorDate: Tue Feb 4 13:39:48 2020 +0800
[Dubbo-perf]: Reduce object allocation for ProtocolUtils.serviceKey(int, String, String, String) (#5525)
---
.../dubbo/rpc/support/GroupServiceKeyCache.java | 71 ++++++++++++++++++++
.../apache/dubbo/rpc/support/ProtocolUtils.java | 23 ++++---
.../dubbo/rpc/support/ProtocolUtilsTest.java | 75 ++++++++++++++++++++++
3 files changed, 157 insertions(+), 12 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/GroupServiceKeyCache.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/GroupServiceKeyCache.java
new file mode 100644
index 0000000..3b37b59
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/GroupServiceKeyCache.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.support;
+
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class GroupServiceKeyCache {
+
+ private final String serviceGroup;
+
+ //ConcurrentMap<serviceName, ConcurrentMap<serviceVersion, ConcurrentMap<port, String>>>
+ private final ConcurrentMap<String, ConcurrentMap<String, ConcurrentMap<Integer, String>>> serviceKeyMap;
+
+ public GroupServiceKeyCache(String serviceGroup) {
+ this.serviceGroup = serviceGroup;
+ this.serviceKeyMap = new ConcurrentHashMap<>(512);
+ }
+
+ public String getServiceKey(String serviceName, String serviceVersion, int port) {
+ ConcurrentMap<String, ConcurrentMap<Integer, String>> versionMap = serviceKeyMap.get(serviceName);
+ if (versionMap == null) {
+ serviceKeyMap.putIfAbsent(serviceName, new ConcurrentHashMap<>());
+ versionMap = serviceKeyMap.get(serviceName);
+ }
+
+ serviceVersion = serviceVersion == null ? "" : serviceVersion;
+ ConcurrentMap<Integer, String> portMap = versionMap.get(serviceVersion);
+ if (portMap == null) {
+ versionMap.putIfAbsent(serviceVersion, new ConcurrentHashMap<>());
+ portMap = versionMap.get(serviceVersion);
+ }
+
+ String serviceKey = portMap.get(port);
+ if (serviceKey == null) {
+ serviceKey = createServiceKey(serviceName, serviceVersion, port);
+ portMap.put(port, serviceKey);
+ }
+ return serviceKey;
+ }
+
+ private String createServiceKey(String serviceName, String serviceVersion, int port) {
+ StringBuilder buf = new StringBuilder();
+ if (StringUtils.isNotEmpty(serviceGroup)) {
+ buf.append(serviceGroup).append('/');
+ }
+
+ buf.append(serviceName);
+ if (StringUtils.isNotEmpty(serviceVersion) && !"0.0.0".equals(serviceVersion)) {
+ buf.append(':').append(serviceVersion);
+ }
+ buf.append(':').append(port);
+ return buf.toString();
+ }
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java
index 769a6a6..801132f 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java
@@ -19,6 +19,9 @@ package org.apache.dubbo.rpc.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_RAW_RETURN;
import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_BEAN;
import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_DEFAULT;
@@ -29,6 +32,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
public class ProtocolUtils {
+ private static final ConcurrentMap<String, GroupServiceKeyCache> groupServiceKeyCacheMap = new ConcurrentHashMap<>();
+
private ProtocolUtils() {
}
@@ -38,19 +43,13 @@ public class ProtocolUtils {
}
public static String serviceKey(int port, String serviceName, String serviceVersion, String serviceGroup) {
- StringBuilder buf = new StringBuilder();
- if (StringUtils.isNotEmpty(serviceGroup)) {
- buf.append(serviceGroup);
- buf.append("/");
- }
- buf.append(serviceName);
- if (serviceVersion != null && serviceVersion.length() > 0 && !"0.0.0".equals(serviceVersion)) {
- buf.append(":");
- buf.append(serviceVersion);
+ serviceGroup = serviceGroup == null ? "" : serviceGroup;
+ GroupServiceKeyCache groupServiceKeyCache = groupServiceKeyCacheMap.get(serviceGroup);
+ if (groupServiceKeyCache == null) {
+ groupServiceKeyCacheMap.putIfAbsent(serviceGroup, new GroupServiceKeyCache(serviceGroup));
+ groupServiceKeyCache = groupServiceKeyCacheMap.get(serviceGroup);
}
- buf.append(":");
- buf.append(port);
- return buf.toString();
+ return groupServiceKeyCache.getServiceKey(serviceName, serviceVersion, port);
}
public static boolean isGeneric(String generic) {
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/ProtocolUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/ProtocolUtilsTest.java
new file mode 100644
index 0000000..eaed8c8
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/rpc/support/ProtocolUtilsTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.support;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ProtocolUtilsTest {
+
+ @Test
+ public void testGetServiceKey() {
+ final String serviceName = "com.abc.demoService";
+ final int port = 1001;
+
+ assertServiceKey(port, serviceName, "1.0.0", "group");
+ assertServiceKey(port, serviceName, "1.0.0", "");
+ assertServiceKey(port, serviceName, "1.0.0", null);
+
+ assertServiceKey(port, serviceName, "0.0", "group");
+ assertServiceKey(port, serviceName, "0_0_0", "group");
+ assertServiceKey(port, serviceName, "0.0.0", "group");
+ assertServiceKey(port, serviceName, "", "group");
+ assertServiceKey(port, serviceName, null, "group");
+
+ assertServiceKey(port, serviceName, "", "");
+ assertServiceKey(port, serviceName, "", null);
+ assertServiceKey(port, serviceName, null, "");
+ assertServiceKey(port, serviceName, null, null);
+
+ assertServiceKey(port, serviceName, "", " ");
+ assertServiceKey(port, serviceName, " ", "");
+ assertServiceKey(port, serviceName, " ", " ");
+ }
+
+ private void assertServiceKey(int port, String serviceName, String serviceVersion, String serviceGroup) {
+ Assertions.assertEquals(
+ serviceKeyOldImpl(port, serviceName, serviceVersion, serviceGroup),
+ ProtocolUtils.serviceKey(port, serviceName, serviceVersion, serviceGroup)
+ );
+ }
+
+ /**
+ * 来自 ProtocolUtils.serviceKey(int, String, String, String) 老版本的实现,用于对比测试!
+ */
+ private static String serviceKeyOldImpl(int port, String serviceName, String serviceVersion, String serviceGroup) {
+ StringBuilder buf = new StringBuilder();
+ if (serviceGroup != null && serviceGroup.length() > 0) {
+ buf.append(serviceGroup);
+ buf.append("/");
+ }
+ buf.append(serviceName);
+ if (serviceVersion != null && serviceVersion.length() > 0 && !"0.0.0".equals(serviceVersion)) {
+ buf.append(":");
+ buf.append(serviceVersion);
+ }
+ buf.append(":");
+ buf.append(port);
+ return buf.toString();
+ }
+
+}