diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
index 948082991c7..3bab435eb6c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
@@ -143,7 +143,13 @@ public class Constants {
public static final int DEFAULT_ALIVE = 60 * 1000;
- public static final int DEFAULT_CONNECTIONS = 0;
+ /**
+ * By default, a consumer JVM instance and a provider JVM instance share a long TCP connection (except when connections are set),
+ * which can set the number of long TCP connections shared to avoid the bottleneck of sharing a single long TCP connection.
+ */
+ public static final String DEFAULT_SHARE_CONNECTIONS = "1";
+
+ public static final String SHARE_CONNECTIONS_KEY = "shareconnections";
public static final int DEFAULT_ACCEPTS = 0;
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
index ce106550601..3a556e7f8c4 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ConsumerConfig.java
@@ -57,6 +57,12 @@ public class ConsumerConfig extends AbstractReferenceConfig {
*/
private Integer queues;
+ /**
+ * By default, a TCP long-connection communication is shared between the consumer process and the provider process.
+ * This property can be set to share multiple TCP long-connection communications. Note that only the dubbo protocol takes effect.
+ */
+ private Integer shareconnections;
+
@Override
public void setTimeout(Integer timeout) {
super.setTimeout(timeout);
@@ -118,4 +124,12 @@ public Integer getQueues() {
public void setQueues(Integer queues) {
this.queues = queues;
}
+
+ public Integer getShareconnections() {
+ return shareconnections;
+ }
+
+ public void setShareconnections(Integer shareconnections) {
+ this.shareconnections = shareconnections;
+ }
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index c5b890c7fc4..41af239deb5 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -891,6 +891,12 @@
+
+
+
+
+
+
diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractClient.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractClient.java
index 4138398f235..2afdc4d0f02 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractClient.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/transport/AbstractClient.java
@@ -174,17 +174,22 @@ public void send(Object message, boolean sent) throws RemotingException {
}
protected void connect() throws RemotingException {
+
connectLock.lock();
+
try {
+
if (isConnected()) {
return;
}
doConnect();
+
if (!isConnected()) {
throw new RemotingException(this, "Failed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
+ ", cause: Connect wait timeout: " + getConnectTimeout() + "ms.");
+
} else {
if (logger.isInfoEnabled()) {
logger.info("Successed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
@@ -192,12 +197,15 @@ protected void connect() throws RemotingException {
+ ", channel is " + this.getChannel());
}
}
+
} catch (RemotingException e) {
throw e;
+
} catch (Throwable e) {
throw new RemotingException(this, "Failed connect to server " + getRemoteAddress() + " from " + getClass().getSimpleName() + " "
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()
+ ", cause: " + e.getMessage(), e);
+
} finally {
connectLock.unlock();
}
@@ -241,11 +249,13 @@ public void reconnect() throws RemotingException {
@Override
public void close() {
+
try {
super.close();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
+
try {
if (executor != null) {
ExecutorUtil.shutdownNow(executor, 100);
@@ -253,11 +263,13 @@ public void close() {
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
+
try {
disconnect();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
+
try {
doClose();
} catch (Throwable e) {
@@ -310,5 +322,4 @@ public String toString() {
* @return channel
*/
protected abstract Channel getChannel();
-
}
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
index e9f42dd56f4..f284dd40dd6 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
@@ -22,7 +22,9 @@
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.serialize.support.SerializableClassRegistry;
import org.apache.dubbo.common.serialize.support.SerializationOptimizer;
+import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
+import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.remoting.Channel;
@@ -49,11 +51,13 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* dubbo protocol support.
@@ -65,6 +69,7 @@ public class DubboProtocol extends AbstractProtocol {
public static final int DEFAULT_PORT = 20880;
private static final String IS_CALLBACK_SERVICE_INVOKE = "_isCallBackServiceInvoke";
private static DubboProtocol INSTANCE;
+
/**
*
*/
@@ -72,8 +77,7 @@ public class DubboProtocol extends AbstractProtocol {
/**
*
*/
- private final Map referenceClientMap = new ConcurrentHashMap<>();
- private final ConcurrentMap ghostClientMap = new ConcurrentHashMap<>();
+ private final Map> referenceClientMap = new ConcurrentHashMap<>();
private final ConcurrentMap locks = new ConcurrentHashMap<>();
private final Set optimizers = new ConcurrentHashSet<>();
/**
@@ -81,55 +85,60 @@ public class DubboProtocol extends AbstractProtocol {
* servicekey-stubmethods
*/
private final ConcurrentMap stubServiceMethodsMap = new ConcurrentHashMap<>();
+
private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {
@Override
public CompletableFuture