This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new 02c9ccaa25 Set reuseAddress option if system supports it (#15239)
02c9ccaa25 is described below
commit 02c9ccaa259059ac5f529edf5c8add1ff7279930
Author: zrlw <[email protected]>
AuthorDate: Thu May 8 09:46:22 2025 +0800
Set reuseAddress option if system supports it (#15239)
---
.../org/apache/dubbo/common/utils/NetUtils.java | 29 ++++++++++++++++++++--
.../apache/dubbo/common/utils/NetUtilsTest.java | 8 ++++++
.../config/spring/SimpleRegistryExporter.java | 9 ++++++-
.../netty/NettyPortUnificationServer.java | 1 +
.../remoting/transport/netty/NettyServer.java | 1 +
.../transport/netty4/NettyTransporterTest.java | 2 ++
.../dubbo/rpc/protocol/tri/TriplePathResolver.java | 2 +-
7 files changed, 48 insertions(+), 4 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 9a8689319c..c32aedbefe 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
@@ -105,6 +105,21 @@ public final class NetUtils {
*/
private static BitSet USED_PORT = new BitSet(65536);
+ private static boolean reuseAddressSupported;
+
+ static {
+ try (ServerSocket serverSocket = new ServerSocket()) {
+ serverSocket.setReuseAddress(true);
+ reuseAddressSupported = true;
+ } catch (Throwable ignored) {
+ // ignore.
+ }
+ }
+
+ public static boolean isReuseAddressSupported() {
+ return reuseAddressSupported;
+ }
+
public static int getRandomPort() {
return RND_PORT_START +
ThreadLocalRandom.current().nextInt(RND_PORT_RANGE);
}
@@ -123,7 +138,12 @@ public final class NetUtils {
if (USED_PORT.get(i)) {
continue;
}
- try (ServerSocket ignored = new ServerSocket(i)) {
+ try (ServerSocket serverSocket = new ServerSocket()) {
+ if (reuseAddressSupported) {
+ // SO_REUSEADDR should be enabled before bind.
+ serverSocket.setReuseAddress(true);
+ }
+ serverSocket.bind(new InetSocketAddress(i));
USED_PORT.set(i);
port = i;
break;
@@ -141,7 +161,12 @@ public final class NetUtils {
* @return true if it's occupied
*/
public static boolean isPortInUsed(int port) {
- try (ServerSocket ignored = new ServerSocket(port)) {
+ try (ServerSocket serverSocket = new ServerSocket()) {
+ if (reuseAddressSupported) {
+ // SO_REUSEADDR should be enabled before bind.
+ serverSocket.setReuseAddress(true);
+ }
+ serverSocket.bind(new InetSocketAddress(port));
return false;
} catch (IOException e) {
// continue
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 7df5221857..d5818d90a1 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
@@ -387,6 +387,14 @@ class NetUtilsTest {
}
}
+ @Test
+ void testRepeatedStatusChecking() {
+ int port = NetUtils.getAvailablePort();
+ for (int i = 0; i < 10000; i++) {
+ assertFalse(NetUtils.isPortInUsed(port));
+ }
+ }
+
private String getIgnoredInterfaces() {
return SystemPropertyConfigUtils.getSystemProperty(
CommonConstants.DubboProperty.DUBBO_NETWORK_IGNORED_INTERFACE);
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/SimpleRegistryExporter.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/SimpleRegistryExporter.java
index 4c1a04fb8f..a52ba5db6c 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/SimpleRegistryExporter.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/SimpleRegistryExporter.java
@@ -25,6 +25,7 @@ import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
import java.io.IOException;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import static
org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;
@@ -45,7 +46,13 @@ public class SimpleRegistryExporter {
public static synchronized Exporter<RegistryService> exportIfAbsent(int
port) {
try {
- new ServerSocket(port).close();
+ ServerSocket serverSocket = new ServerSocket();
+ if (NetUtils.isReuseAddressSupported()) {
+ // SO_REUSEADDR should be enabled before bind.
+ serverSocket.setReuseAddress(true);
+ }
+ serverSocket.bind(new InetSocketAddress(port));
+ serverSocket.close();
return export(port);
} catch (IOException e) {
return null;
diff --git
a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyPortUnificationServer.java
b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyPortUnificationServer.java
index ad353fc45e..f35e743aab 100644
---
a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyPortUnificationServer.java
+++
b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyPortUnificationServer.java
@@ -101,6 +101,7 @@ public class NettyPortUnificationServer extends
AbstractPortUnificationServer {
// final Timer timer = new HashedWheelTimer(new
NamedThreadFactory("NettyIdleTimer", true));
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("backlog",
getUrl().getPositiveParameter(BACKLOG_KEY, Constants.DEFAULT_BACKLOG));
+ bootstrap.setOption("reuseAddress", true);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() {
diff --git
a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
index 42a2346481..95a6dadfad 100644
---
a/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
+++
b/dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyServer.java
@@ -84,6 +84,7 @@ public class NettyServer extends AbstractServer implements
RemotingServer {
// final Timer timer = new HashedWheelTimer(new
NamedThreadFactory("NettyIdleTimer", true));
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("backlog",
getUrl().getPositiveParameter(BACKLOG_KEY, Constants.DEFAULT_BACKLOG));
+ bootstrap.setOption("reuseAddress", true);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() {
diff --git
a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
index 3267f90834..b36649613d 100644
---
a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
+++
b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/NettyTransporterTest.java
@@ -32,6 +32,7 @@ import org.apache.dubbo.rpc.model.ModuleModel;
import java.util.concurrent.CountDownLatch;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static
org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_DEFAULT;
@@ -59,6 +60,7 @@ class NettyTransporterTest {
RemotingServer server = new NettyTransporter().bind(url, new
ChannelHandlerAdapter());
assertThat(server.isBound(), is(true));
+ Assertions.assertNotEquals(port, NetUtils.getAvailablePort(port));
}
@Test
diff --git
a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriplePathResolver.java
b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriplePathResolver.java
index d1f20d77fa..da41ff0ee4 100644
---
a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriplePathResolver.java
+++
b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriplePathResolver.java
@@ -28,7 +28,7 @@ import java.util.Map;
public class TriplePathResolver implements PathResolver {
- private static final Logger LOGGER =
LoggerFactory.getLogger(TripleProtocol.class);
+ private static final Logger LOGGER =
LoggerFactory.getLogger(TriplePathResolver.class);
private final Map<String, Invoker<?>> mapping =
CollectionUtils.newConcurrentHashMap();
private final Map<String, Boolean> nativeStubs =
CollectionUtils.newConcurrentHashMap();