You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@seata.apache.org by ji...@apache.org on 2026/05/27 04:44:49 UTC
(incubator-seata) branch 2.x updated: optimize: support ignored network interfaces configuration (#8090)
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: 徐晓伟 <xu...@xuxiaowei.com.cn>
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: notifications-unsubscribe@seata.apache.org
For additional commands, e-mail: notifications-help@seata.apache.org