搜索 K
Appearance
Appearance
/etc/hosts 或 DNS 配置不当,可能返回 127.0.0.1 或错误 IP。遍历所有网络接口,筛选符合条件的 IP:
package robot.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* @author zhangch
* @version 1.0
* @date 2025/5/10 13:33
* @description
*/
public class NetworkUtils {
private static final Logger log = LoggerFactory.getLogger(NetworkUtils.class);
// 统一获取 IP 地址(适配多环境)
public static String getAdaptiveIp() {
if (EnvironmentUtils.isRunningInDocker()) {
// Docker 环境优先读取宿主机的 HOST_IP 环境变量
String hostIp = System.getenv("HOST_IP");
if (hostIp != null) return hostIp;
// 使用特定网络名称获取IP地址
if (getOvsIp() != null) return getOvsIp();
}
// 物理机环境使用通用 IP 获取逻辑
return getLocalIp();
}
private static String getOvsIp() {
try {
NetworkInterface ovsInterface = NetworkInterface.getByName("ovs_eth0");
if (ovsInterface != null && ovsInterface.isUp()) {
Enumeration<InetAddress> addresses = ovsInterface.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
return addr.getHostAddress();
}
}
}
} catch (SocketException e) {
log.error("Failed to access network interfaces: {}", e.getMessage());
throw new RuntimeException(e);
}
return null;
}
/**
* 获取本机有效 IPv4 地址(排除回环地址、虚拟接口等)
*/
private static String getLocalIp() {
try {
List<String> ipList = new ArrayList<>();
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
// 排除虚拟接口、未启用的接口
if (iface.isLoopback() || !iface.isUp() || iface.isVirtual()) {
continue;
}
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
// 仅处理 IPv4 地址
if (addr instanceof Inet4Address) {
String ip = addr.getHostAddress();
// 排除 127.0.0.1 等回环地址
if (!addr.isLoopbackAddress()) {
ipList.add(ip);
}
}
}
}
if (!ipList.isEmpty()) {
// 返回第一个非回环地址,或按需选择特定 IP
return ipList.get(0);
} else {
return "127.0.0.1";
//throw new RuntimeException("No valid IPv4 address found");
}
} catch (SocketException e) {
log.error("Failed to get network interfaces: {}", e.getMessage());
throw new RuntimeException(e);
}
}
}package robot.util;
import java.io.File;
/**
* @author zhangch
* @version 1.0
* @date 2025/5/10 13:35
* @description
*/
public class EnvironmentUtils {
// 检测是否运行在 Docker 容器中
public static boolean isRunningInDocker() {
File dockerEnvFile = new File("/.dockerenv");
return dockerEnvFile.exists();
}
// 获取操作系统类型
public static String getOsType() {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
return "windows";
} else if (os.contains("nix") || os.contains("nux")) {
return "linux";
} else {
return "other";
}
}
}try {
String ip = NetworkUtils.getLocalIp();
log.info("本机 IP: {}", ip);
} catch (RuntimeException e) {
log.error("获取 IP 失败", e);
// 降级处理(如使用默认值)
String fallbackIp = "127.0.0.1";
}| 优化项 | 说明 |
|---|---|
| 多网卡支持 | 遍历所有网络接口,避免依赖单一接口 |
| 过滤无效地址 | 排除回环地址 (127.0.0.1)、虚拟接口、未启用接口 |
| 明确 IPv4 优先 | 通过 Inet4Address 确保只获取 IPv4 地址 |
| 异常处理 | 统一捕获 SocketException,日志记录更清晰 |
| 可扩展性 | 返回 IP 列表 (ipList),方便后续按需选择(如优先选择内网/外网地址) |
容器环境:
HOST_IP)。**IPv6 支持:
if (addr instanceof Inet6Address) {
// 处理 IPv6 逻辑
}