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/01 07:59:06 UTC
[dubbo] branch master updated: perf: Reduce object allocation for
ContextFilter.invoke(Invoker,
Invocation) and NetUtils.isInvalidLocalHost(String) (#5542)
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 c355a1a perf: Reduce object allocation for ContextFilter.invoke(Invoker, Invocation) and NetUtils.isInvalidLocalHost(String) (#5542)
c355a1a is described below
commit c355a1a836fd831d6f1f31f2c0763d6f0647e26e
Author: LinShunKang <li...@gmail.com>
AuthorDate: Sat Feb 1 15:58:59 2020 +0800
perf: Reduce object allocation for ContextFilter.invoke(Invoker, Invocation) and NetUtils.isInvalidLocalHost(String) (#5542)
---
.../org/apache/dubbo/common/utils/NetUtils.java | 5 +-
.../apache/dubbo/common/utils/NetUtilsTest.java | 8 +-
.../org/apache/dubbo/rpc/filter/ContextFilter.java | 258 +++++++++++----------
3 files changed, 146 insertions(+), 125 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
index ee2aa61..6dfab2e 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
@@ -46,9 +46,10 @@ import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
* IP and Port Helper for RPC
*/
public class NetUtils {
+
private static Logger logger;
- {
+ static {
logger = LoggerFactory.getLogger(NetUtils.class);
if (logger instanceof FailsafeLogger) {
logger = ((FailsafeLogger) logger).getLogger();
@@ -123,7 +124,7 @@ public class NetUtils {
|| host.length() == 0
|| host.equalsIgnoreCase(LOCALHOST_KEY)
|| host.equals(ANYHOST_VALUE)
- || (LOCAL_IP_PATTERN.matcher(host).matches());
+ || host.startsWith("127.");
}
public static boolean isValidLocalHost(String host) {
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java
index f690ef7..9e0abde 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/NetUtilsTest.java
@@ -39,6 +39,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class NetUtilsTest {
+
@Test
public void testGetRandomPort() throws Exception {
assertThat(NetUtils.getRandomPort(), greaterThanOrEqualTo(30000));
@@ -87,11 +88,14 @@ public class NetUtilsTest {
assertTrue(NetUtils.isInvalidLocalHost("localhost"));
assertTrue(NetUtils.isInvalidLocalHost("0.0.0.0"));
assertTrue(NetUtils.isInvalidLocalHost("127.1.2.3"));
+ assertTrue(NetUtils.isInvalidLocalHost("127.0.0.1"));
+ assertFalse(NetUtils.isInvalidLocalHost("128.0.0.1"));
}
@Test
public void testIsValidLocalHost() throws Exception {
assertTrue(NetUtils.isValidLocalHost("1.2.3.4"));
+ assertTrue(NetUtils.isValidLocalHost("128.0.0.1"));
}
@Test
@@ -243,7 +247,7 @@ public class NetUtilsTest {
assertTrue(thrown.getMessage().contains("If you config ip expression that contains '*'"));
thrown = assertThrows(IllegalArgumentException.class, () ->
- NetUtils.matchIpRange("234e:0:4567:3d", "234e:0:4567::3d:ff", 90));
+ NetUtils.matchIpRange("234e:0:4567:3d", "234e:0:4567::3d:ff", 90));
assertTrue(thrown.getMessage().contains("The host is ipv6, but the pattern is not ipv6 pattern"));
thrown =
@@ -282,7 +286,7 @@ public class NetUtilsTest {
@Test
public void testMatchIpv4WithIpPort() throws UnknownHostException {
NumberFormatException thrown =
- assertThrows(NumberFormatException.class, () ->NetUtils.matchIpExpression("192.168.1.192/26:90", "192.168.1.199", 90));
+ assertThrows(NumberFormatException.class, () -> NetUtils.matchIpExpression("192.168.1.192/26:90", "192.168.1.199", 90));
assertTrue(thrown instanceof NumberFormatException);
assertTrue(NetUtils.matchIpRange("*.*.*.*:90", "192.168.1.63", 90));
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
index e771f72..09520cd 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
@@ -1,121 +1,137 @@
-/*
- * 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.filter;
-
-import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.Filter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
-import static org.apache.dubbo.rpc.Constants.FORCE_USE_TAG;
-import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
-
-
-/**
- * ContextFilter set the provider RpcContext with invoker, invocation, local port it is using and host for
- * current execution thread.
- *
- * @see RpcContext
- */
-@Activate(group = PROVIDER, order = -10000)
-public class ContextFilter implements Filter, Filter.Listener2 {
- private static final String TAG_KEY = "dubbo.tag";
-
- @Override
- public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
- Map<String, Object> attachments = invocation.getAttachments();
- if (attachments != null) {
- attachments = new HashMap<>(attachments);
- attachments.remove(PATH_KEY);
- attachments.remove(INTERFACE_KEY);
- attachments.remove(GROUP_KEY);
- attachments.remove(VERSION_KEY);
- attachments.remove(DUBBO_VERSION_KEY);
- attachments.remove(TOKEN_KEY);
- attachments.remove(TIMEOUT_KEY);
- // Remove async property to avoid being passed to the following invoke chain.
- attachments.remove(ASYNC_KEY);
- attachments.remove(TAG_KEY);
- attachments.remove(FORCE_USE_TAG);
- }
- RpcContext context = RpcContext.getContext();
-
- context.setInvoker(invoker)
- .setInvocation(invocation)
-// .setAttachments(attachments) // merged from dubbox
- .setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort());
- String remoteApplication = (String) invocation.getAttachment(REMOTE_APPLICATION_KEY);
- if (StringUtils.isNotEmpty(remoteApplication)) {
- context.setRemoteApplicationName(remoteApplication);
- } else {
- context.setRemoteApplicationName((String) RpcContext.getContext().getAttachment(REMOTE_APPLICATION_KEY));
-
- }
-
-
- // merged from dubbox
- // we may already added some attachments into RpcContext before this filter (e.g. in rest protocol)
- if (attachments != null) {
- if (RpcContext.getContext().getAttachments() != null) {
- RpcContext.getContext().getAttachments().putAll(attachments);
- } else {
- RpcContext.getContext().setAttachments(attachments);
- }
- }
-
- if (invocation instanceof RpcInvocation) {
- ((RpcInvocation) invocation).setInvoker(invoker);
- }
- try {
- RpcContext.getContext().clearAfterEachInvoke(false);
- return invoker.invoke(invocation);
- } finally {
- RpcContext.getContext().clearAfterEachInvoke(true);
- // IMPORTANT! For async scenario, we must remove context from current thread, so we always create a new RpcContext for the next invoke for the same thread.
- RpcContext.removeContext();
- RpcContext.removeServerContext();
- }
- }
-
- @Override
- public void onMessage(Result appResponse, Invoker<?> invoker, Invocation invocation) {
- // pass attachments to result
- appResponse.addAttachments(RpcContext.getServerContext().getAttachments());
- }
-
- @Override
- public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
-
- }
-}
+/*
+ * 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.filter;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
+import static org.apache.dubbo.rpc.Constants.FORCE_USE_TAG;
+import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
+
+
+/**
+ * ContextFilter set the provider RpcContext with invoker, invocation, local port it is using and host for
+ * current execution thread.
+ *
+ * @see RpcContext
+ */
+@Activate(group = PROVIDER, order = -10000)
+public class ContextFilter implements Filter, Filter.Listener2 {
+
+ private static final String TAG_KEY = "dubbo.tag";
+
+ private static final Set<String> UNLOADING_KEYS;
+
+ static {
+ UNLOADING_KEYS = new HashSet<>(128);
+ UNLOADING_KEYS.add(PATH_KEY);
+ UNLOADING_KEYS.add(INTERFACE_KEY);
+ UNLOADING_KEYS.add(GROUP_KEY);
+ UNLOADING_KEYS.add(VERSION_KEY);
+ UNLOADING_KEYS.add(DUBBO_VERSION_KEY);
+ UNLOADING_KEYS.add(TOKEN_KEY);
+ UNLOADING_KEYS.add(TIMEOUT_KEY);
+
+ // Remove async property to avoid being passed to the following invoke chain.
+ UNLOADING_KEYS.add(ASYNC_KEY);
+ UNLOADING_KEYS.add(TAG_KEY);
+ UNLOADING_KEYS.add(FORCE_USE_TAG);
+ }
+
+ @Override
+ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+ Map<String, Object> attachments = invocation.getAttachments();
+ if (attachments != null) {
+ Map<String, Object> newAttach = new HashMap<>(attachments.size());
+ for (Map.Entry<String, Object> entry : attachments.entrySet()) {
+ String key = entry.getKey();
+ if (!UNLOADING_KEYS.contains(key)) {
+ newAttach.put(key, entry.getValue());
+ }
+ }
+ attachments = newAttach;
+ }
+
+ RpcContext context = RpcContext.getContext();
+ context.setInvoker(invoker)
+ .setInvocation(invocation)
+// .setAttachments(attachments) // merged from dubbox
+ .setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort());
+ String remoteApplication = (String) invocation.getAttachment(REMOTE_APPLICATION_KEY);
+ if (StringUtils.isNotEmpty(remoteApplication)) {
+ context.setRemoteApplicationName(remoteApplication);
+ } else {
+ context.setRemoteApplicationName((String) context.getAttachment(REMOTE_APPLICATION_KEY));
+ }
+
+ // merged from dubbox
+ // we may already added some attachments into RpcContext before this filter (e.g. in rest protocol)
+ if (attachments != null) {
+ if (context.getAttachments() != null) {
+ context.getAttachments().putAll(attachments);
+ } else {
+ context.setAttachments(attachments);
+ }
+ }
+
+ if (invocation instanceof RpcInvocation) {
+ ((RpcInvocation) invocation).setInvoker(invoker);
+ }
+
+ try {
+ context.clearAfterEachInvoke(false);
+ return invoker.invoke(invocation);
+ } finally {
+ context.clearAfterEachInvoke(true);
+ // IMPORTANT! For async scenario, we must remove context from current thread, so we always create a new RpcContext for the next invoke for the same thread.
+ RpcContext.removeContext();
+ RpcContext.removeServerContext();
+ }
+ }
+
+ @Override
+ public void onMessage(Result appResponse, Invoker<?> invoker, Invocation invocation) {
+ // pass attachments to result
+ appResponse.addAttachments(RpcContext.getServerContext().getAttachments());
+ }
+
+ @Override
+ public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
+
+ }
+}