This is an automated email from the ASF dual-hosted git repository.

slievrly pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new bff103bde8 optimize: support ignored network interfaces configuration 
(#8090)
bff103bde8 is described below

commit bff103bde8722b1aac2d222d196e84b1dc051d58
Author: 徐晓伟 <[email protected]>
AuthorDate: Wed May 27 12:44:45 2026 +0800

    optimize: support ignored network interfaces configuration (#8090)
---
 changes/en-us/2.x.md                               |   1 +
 changes/zh-cn/2.x.md                               |   1 +
 .../java/org/apache/seata/common/util/NetUtil.java |  68 +++++++++-
 .../org/apache/seata/common/util/NetUtilTest.java  | 139 +++++++++++++++++++++
 .../main/java/org/apache/seata/server/Server.java  |  20 ++-
 server/src/main/resources/application.example.yml  |   3 +
 .../main/resources/application.raft.example.yml    |   7 +-
 .../boot/autoconfigure/StarterConstants.java       |  11 ++
 8 files changed, 243 insertions(+), 7 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 26ab33c379..2b3ffbf2bd 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -34,6 +34,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#8044](https://github.com/apache/incubator-seata/pull/8044)] add protobuf 
serialization support for UnregisterRM protocol
 - [[#8046](https://github.com/apache/incubator-seata/pull/8046)] add fastjson2 
and jackson3
 - [[#7952](https://github.com/apache/incubator-seata/pull/7952)] Support 
runtime dynamic switching between HTTP/1.1 and HTTP/2 for Raft client watch, 
with a 2.7.0 version threshold and compatibility fallback
+- [[#8090](https://github.com/apache/incubator-seata/pull/8090)] support 
ignored network interfaces configuration
 
 ### bugfix:
 
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 63b6a88ef8..36c0ecc95d 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -35,6 +35,7 @@
 - [[#8044](https://github.com/apache/incubator-seata/pull/8044)] 为 
UnregisterRM 协议添加 protobuf 序列化支持
 - [[#8046](https://github.com/apache/incubator-seata/pull/8046)] 添加了 fastjson2 
和 jackson3
 - [[#7952](https://github.com/apache/incubator-seata/pull/7952)] 
在Raft客户端支持Watch在HTTP/1.1与HTTP/2之间运行时动态切换
+- [[#8090](https://github.com/apache/incubator-seata/pull/8090)] 支持忽略的网络接口配置
 
 
 ### bugfix:
diff --git a/common/src/main/java/org/apache/seata/common/util/NetUtil.java 
b/common/src/main/java/org/apache/seata/common/util/NetUtil.java
index 357d5cb6f6..b75a14e9a8 100644
--- a/common/src/main/java/org/apache/seata/common/util/NetUtil.java
+++ b/common/src/main/java/org/apache/seata/common/util/NetUtil.java
@@ -189,7 +189,22 @@ public class NetUtil {
      * @return the local ip
      */
     public static String getLocalIp(String... preferredNetworks) {
-        InetAddress address = getLocalAddress(preferredNetworks);
+        return getIgnoredInterfacesLocalIp(null, preferredNetworks);
+    }
+
+    /**
+     * Gets local ip with network interface filtering support.
+     * This method allows filtering out unwanted network interfaces (e.g., 
virtual interfaces)
+     * and selecting preferred networks based on patterns.
+     *
+     * @param ignoredInterfaces the network interface name patterns to ignore 
(regex supported),
+     *                          e.g., "VMware.*", "VirtualBox.*", "docker.*", 
"veth.*"
+     * @param preferredNetworks the preferred network address patterns (regex 
or prefix match),
+     *                          e.g., "192.168.*", "10.0.*"
+     * @return the local ip address, or localhost if not found
+     */
+    public static String getIgnoredInterfacesLocalIp(String[] 
ignoredInterfaces, String... preferredNetworks) {
+        InetAddress address = 
getIgnoredInterfacesLocalAddress(ignoredInterfaces, preferredNetworks);
         if (null != address) {
             String hostAddress = address.getHostAddress();
             if (address instanceof Inet6Address) {
@@ -227,15 +242,38 @@ public class NetUtil {
      * @return the local address
      */
     public static InetAddress getLocalAddress(String... preferredNetworks) {
+        return getIgnoredInterfacesLocalAddress(null, preferredNetworks);
+    }
+
+    /**
+     * Gets local address with network interface filtering support.
+     * This method allows filtering out unwanted network interfaces (e.g., 
virtual interfaces)
+     * and selecting preferred networks based on patterns.
+     * <p>
+     * Note: Does not support IPv6.
+     * <p>
+     * Selection priority:
+     * 1. Filter out interfaces matching ignoredInterfaces patterns
+     * 2. If preferredNetworks is specified, return the first matching address
+     * 3. If no match found, return the first valid IP address
+     *
+     * @param ignoredInterfaces the network interface name patterns to ignore 
(regex supported),
+     *                          e.g., "VMware.*", "VirtualBox.*", "docker.*", 
"veth.*"
+     * @param preferredNetworks the preferred network address patterns (regex 
or prefix match),
+     *                          e.g., "192.168.*", "10.0.*"
+     * @return the local address, or null if not found
+     */
+    public static InetAddress getIgnoredInterfacesLocalAddress(
+            String[] ignoredInterfaces, String... preferredNetworks) {
         if (LOCAL_ADDRESS != null) {
             return LOCAL_ADDRESS;
         }
-        InetAddress localAddress = getLocalAddress0(preferredNetworks);
+        InetAddress localAddress = getLocalAddress0(ignoredInterfaces, 
preferredNetworks);
         LOCAL_ADDRESS = localAddress;
         return localAddress;
     }
 
-    private static InetAddress getLocalAddress0(String... preferredNetworks) {
+    private static InetAddress getLocalAddress0(String[] ignoredInterfaces, 
String... preferredNetworks) {
         InetAddress localAddress = null;
         try {
             Enumeration<NetworkInterface> interfaces = 
NetworkInterface.getNetworkInterfaces();
@@ -244,6 +282,9 @@ public class NetUtil {
                     try {
                         NetworkInterface network = interfaces.nextElement();
                         if (network.isUp()) {
+                            if (ignoreInterface(ignoredInterfaces, 
network.getDisplayName())) {
+                                continue;
+                            }
                             Enumeration<InetAddress> addresses = 
network.getInetAddresses();
                             while (addresses.hasMoreElements()) {
                                 try {
@@ -291,6 +332,27 @@ public class NetUtil {
         return localAddress;
     }
 
+    /**
+     * Check if the network interface should be ignored based on the provided 
patterns.
+     * Supports regex matching for flexible interface name filtering.
+     *
+     * @param ignoredInterfaces array of regex patterns to match against 
interface names, null means no filtering
+     * @param interfaceName the display name of the network interface to check
+     * @return true if the interface matches any ignore pattern and should be 
skipped, false otherwise
+     */
+    public static boolean ignoreInterface(String[] ignoredInterfaces, String 
interfaceName) {
+        if (ignoredInterfaces == null) {
+            return false;
+        }
+        for (String regex : ignoredInterfaces) {
+            if (interfaceName.matches(regex)) {
+                LOGGER.trace("Ignoring interface: {}", interfaceName);
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Valid address.
      *
diff --git a/common/src/test/java/org/apache/seata/common/util/NetUtilTest.java 
b/common/src/test/java/org/apache/seata/common/util/NetUtilTest.java
index 76e8d7a0cf..bcf8f047dd 100644
--- a/common/src/test/java/org/apache/seata/common/util/NetUtilTest.java
+++ b/common/src/test/java/org/apache/seata/common/util/NetUtilTest.java
@@ -276,4 +276,143 @@ public class NetUtilTest {
         String localIP = NetUtil.localIP();
         assertThat(localIP).isIn("127.0.0.1", "0:0:0:0:0:0:0:1");
     }
+
+    /**
+     * Test ignore interface with null ignored interfaces.
+     */
+    @Test
+    public void testIgnoreInterface_withNullIgnoredInterfaces() {
+        // When ignoredInterfaces is null, should not ignore any interface
+        assertThat(NetUtil.ignoreInterface(null, "eth0")).isFalse();
+        assertThat(NetUtil.ignoreInterface(null, "VMware Virtual Ethernet 
Adapter"))
+                .isFalse();
+        assertThat(NetUtil.ignoreInterface(null, "docker0")).isFalse();
+    }
+
+    /**
+     * Test ignore interface with empty ignored interfaces.
+     */
+    @Test
+    public void testIgnoreInterface_withEmptyIgnoredInterfaces() {
+        // When ignoredInterfaces is empty array, should not ignore any 
interface
+        String[] emptyIgnored = new String[0];
+        assertThat(NetUtil.ignoreInterface(emptyIgnored, "eth0")).isFalse();
+        assertThat(NetUtil.ignoreInterface(emptyIgnored, "VMware Virtual 
Ethernet Adapter"))
+                .isFalse();
+    }
+
+    /**
+     * Test ignore interface with exact match.
+     */
+    @Test
+    public void testIgnoreInterface_withExactMatch() {
+        String[] ignoredInterfaces = new String[] {"docker0", "veth.*", 
"VMware.*"};
+
+        // Exact match
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"docker0")).isTrue();
+
+        // Should not match
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"eth0")).isFalse();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"en0")).isFalse();
+    }
+
+    /**
+     * Test ignore interface with regex pattern.
+     */
+    @Test
+    public void testIgnoreInterface_withRegexPattern() {
+        String[] ignoredInterfaces = new String[] {"VMware.*", "VirtualBox.*", 
"docker.*", "veth.*", "br-.*"};
+
+        // VMware interfaces
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, "VMware Virtual 
Ethernet Adapter"))
+                .isTrue();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, "VMware Network 
Adapter"))
+                .isTrue();
+
+        // VirtualBox interfaces
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, "VirtualBox 
Host-Only Network"))
+                .isTrue();
+
+        // Docker interfaces
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"docker0")).isTrue();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"docker1")).isTrue();
+
+        // veth interfaces (Docker container interfaces)
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"veth1234567")).isTrue();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"vethab12cd")).isTrue();
+
+        // bridge interfaces
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"br-1234567890ab"))
+                .isTrue();
+
+        // Should not match normal interfaces
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"eth0")).isFalse();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"en0")).isFalse();
+        assertThat(NetUtil.ignoreInterface(ignoredInterfaces, 
"wlan0")).isFalse();
+    }
+
+    /**
+     * Test get ignored interfaces local ip with null ignored interfaces.
+     */
+    @Test
+    public void testGetIgnoredInterfacesLocalIp_withNullIgnoredInterfaces() {
+        // Should work the same as getLocalIp when ignoredInterfaces is null
+        String ip = NetUtil.getIgnoredInterfacesLocalIp(null);
+        assertThat(ip).isNotNull();
+        assertThat(ip).isNotEmpty();
+    }
+
+    /**
+     * Test get ignored interfaces local ip with ignored interfaces.
+     */
+    @Test
+    public void testGetIgnoredInterfacesLocalIp_withIgnoredInterfaces() {
+        // Test with common virtual interface patterns
+        String[] ignoredInterfaces = new String[] {"VMware.*", "VirtualBox.*", 
"docker.*", "veth.*"};
+        String ip = NetUtil.getIgnoredInterfacesLocalIp(ignoredInterfaces);
+        assertThat(ip).isNotNull();
+        assertThat(ip).isNotEmpty();
+    }
+
+    /**
+     * Test get ignored interfaces local ip with preferred networks.
+     */
+    @Test
+    public void testGetIgnoredInterfacesLocalIp_withPreferredNetworks() {
+        String[] ignoredInterfaces = new String[] {"VMware.*", "VirtualBox.*"};
+        String[] preferredNetworks = new String[] {"192.168.*", "10.*"};
+        String ip = NetUtil.getIgnoredInterfacesLocalIp(ignoredInterfaces, 
preferredNetworks);
+        assertThat(ip).isNotNull();
+        assertThat(ip).isNotEmpty();
+    }
+
+    /**
+     * Test get ignored interfaces local address with null ignored interfaces.
+     */
+    @Test
+    public void 
testGetIgnoredInterfacesLocalAddress_withNullIgnoredInterfaces() {
+        // Should work the same as getLocalAddress when ignoredInterfaces is 
null
+        assertThat(NetUtil.getIgnoredInterfacesLocalAddress(null)).isNotNull();
+    }
+
+    /**
+     * Test get ignored interfaces local address with ignored interfaces.
+     */
+    @Test
+    public void testGetIgnoredInterfacesLocalAddress_withIgnoredInterfaces() {
+        // Test with common virtual interface patterns
+        String[] ignoredInterfaces = new String[] {"VMware.*", "VirtualBox.*", 
"docker.*", "veth.*", "br-.*"};
+        
assertThat(NetUtil.getIgnoredInterfacesLocalAddress(ignoredInterfaces)).isNotNull();
+    }
+
+    /**
+     * Test get ignored interfaces local address with preferred networks.
+     */
+    @Test
+    public void testGetIgnoredInterfacesLocalAddress_withPreferredNetworks() {
+        String[] ignoredInterfaces = new String[] {"VMware.*", "VirtualBox.*"};
+        String[] preferredNetworks = new String[] {"192.168.*", "10.*"};
+        assertThat(NetUtil.getIgnoredInterfacesLocalAddress(ignoredInterfaces, 
preferredNetworks))
+                .isNotNull();
+    }
 }
diff --git a/server/src/main/java/org/apache/seata/server/Server.java 
b/server/src/main/java/org/apache/seata/server/Server.java
index 32b7902682..9c2a579495 100644
--- a/server/src/main/java/org/apache/seata/server/Server.java
+++ b/server/src/main/java/org/apache/seata/server/Server.java
@@ -43,6 +43,7 @@ import java.util.concurrent.TimeUnit;
 
 import static 
org.apache.seata.common.Constants.OBJECT_KEY_SPRING_APPLICATION_CONTEXT;
 import static 
org.apache.seata.spring.boot.autoconfigure.StarterConstants.REGEX_SPLIT_CHAR;
+import static 
org.apache.seata.spring.boot.autoconfigure.StarterConstants.REGISTRY_IGNORED_INTERFACES;
 import static 
org.apache.seata.spring.boot.autoconfigure.StarterConstants.REGISTRY_PREFERRED_NETWORKS;
 
 /**
@@ -81,11 +82,26 @@ public class Server {
         if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
             XID.setIpAddress(parameterParser.getHost());
         } else {
+            // Get preferred network patterns from configuration (regex or 
prefix match)
+            // Used to select specific network interfaces when multiple are 
available
             String preferredNetworks = 
ConfigurationFactory.getInstance().getConfig(REGISTRY_PREFERRED_NETWORKS);
+
+            // Get ignored interface patterns from configuration (regex 
supported)
+            // Useful for filtering out virtual interfaces like VMware, 
VirtualBox, Docker, etc.
+            // Example: "VMware.*,VirtualBox.*,bridge.*,docker.*,veth.*"
+            String ignoredInterfaces = 
ConfigurationFactory.getInstance().getConfig(REGISTRY_IGNORED_INTERFACES);
+            String[] ignoredInterfacesSplit = null;
+            if (ignoredInterfaces != null) {
+                ignoredInterfacesSplit = ignoredInterfaces.split(",");
+            }
+
+            // Get local IP address with interface filtering
+            // Priority: ignored interfaces filter -> preferred networks match 
-> first valid IP
             if (StringUtils.isNotBlank(preferredNetworks)) {
-                
XID.setIpAddress(NetUtil.getLocalIp(preferredNetworks.split(REGEX_SPLIT_CHAR)));
+                XID.setIpAddress(NetUtil.getIgnoredInterfacesLocalIp(
+                        ignoredInterfacesSplit, 
preferredNetworks.split(REGEX_SPLIT_CHAR)));
             } else {
-                XID.setIpAddress(NetUtil.getLocalIp());
+                
XID.setIpAddress(NetUtil.getIgnoredInterfacesLocalIp(ignoredInterfacesSplit));
             }
         }
         NettyRemotingServer nettyRemotingServer = new 
NettyRemotingServer(workingThreads);
diff --git a/server/src/main/resources/application.example.yml 
b/server/src/main/resources/application.example.yml
index 44771ad6a6..eff0d0bbbe 100644
--- a/server/src/main/resources/application.example.yml
+++ b/server/src/main/resources/application.example.yml
@@ -85,6 +85,9 @@ seata:
     # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa 、 seata
     type: file
     preferred-networks: 30.240.*
+    # Network interface name patterns to ignore when determining local IP 
(regex supported).
+    # Useful for filtering out virtual interfaces like VMware, VirtualBox, 
Docker, etc.
+    ignored-interfaces: VMware.*
     metadata:
       weight: 100
     seata:
diff --git a/server/src/main/resources/application.raft.example.yml 
b/server/src/main/resources/application.raft.example.yml
index 92869ea449..1016333b28 100644
--- a/server/src/main/resources/application.raft.example.yml
+++ b/server/src/main/resources/application.raft.example.yml
@@ -82,6 +82,9 @@ seata:
     # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa 、 seata
     type: file
     preferred-networks: 30.240.*
+    # Network interface name patterns to ignore when determining local IP 
(regex supported).
+    # Useful for filtering out virtual interfaces like VMware, VirtualBox, 
Docker, etc.
+    ignored-interfaces: VMware.*
     seata:
       server-addr: 127.0.0.1:8081
       cluster: default
@@ -112,12 +115,12 @@ seata:
         client:
           keystore:
             path: ssl/cbolt.pfx
-            password: 
+            password:
             type: pkcs12
         server:
           keystore:
             path: ssl/bolt.pfx
-            password: 
+            password:
             type: pkcs12
         kmf-algorithm: SunX509
         tmf-algorithm: SunX509
diff --git 
a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java
 
b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java
index 1d18cc03c0..e63341fed0 100644
--- 
a/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java
+++ 
b/spring/seata-spring-autoconfigure/seata-spring-autoconfigure-core/src/main/java/org/apache/seata/spring/boot/autoconfigure/StarterConstants.java
@@ -46,7 +46,18 @@ public interface StarterConstants {
     String SAGA_ASYNC_THREAD_POOL_PREFIX = SAGA_STATE_MACHINE_PREFIX + 
".async-thread-pool";
 
     String REGISTRY_PREFIX = SEATA_PREFIX + ".registry";
+    /**
+     * Configuration key for preferred network address patterns (regex or 
prefix match).
+     * Used to select specific network interfaces when multiple are available.
+     */
     String REGISTRY_PREFERRED_NETWORKS = ConfigurationKeys.FILE_ROOT_REGISTRY 
+ ".preferredNetworks";
+    /**
+     * Configuration key for network interface name patterns to ignore (regex 
supported).
+     * Useful for filtering out virtual interfaces like VMware, VirtualBox, 
Docker, etc.
+     * Example value: "VMware.*,VirtualBox.*,bridge.*,docker.*,veth.*"
+     */
+    String REGISTRY_IGNORED_INTERFACES = ConfigurationKeys.FILE_ROOT_REGISTRY 
+ ".ignoredInterfaces";
+
     String REGISTRY_NACOS_PREFIX = REGISTRY_PREFIX + ".nacos";
     String REGISTRY_RAFT_PREFIX = REGISTRY_PREFIX + ".raft";
     String REGISTRY_EUREKA_PREFIX = REGISTRY_PREFIX + ".eureka";


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to