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();

Reply via email to