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]