diff --git a/common/src/main/java/org/apache/rocketmq/common/MixAll.java b/common/src/main/java/org/apache/rocketmq/common/MixAll.java index f8e9b4e1f673..5c4795baf293 100644 --- a/common/src/main/java/org/apache/rocketmq/common/MixAll.java +++ b/common/src/main/java/org/apache/rocketmq/common/MixAll.java @@ -26,6 +26,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; @@ -407,12 +408,50 @@ private static String localhost() { InetAddress addr = InetAddress.getLocalHost(); return addr.getHostAddress(); } catch (Throwable e) { + try { + String candidatesHost = getLocalhostByNetworkInterface(); + if (candidatesHost != null) + return candidatesHost; + + } catch (Exception ignored) { + } + throw new RuntimeException("InetAddress java.net.InetAddress.getLocalHost() throws UnknownHostException" + FAQUrl.suggestTodo(FAQUrl.UNKNOWN_HOST_EXCEPTION), e); } } + private static String getLocalhostByNetworkInterface() throws SocketException { + List candidatesHost = new ArrayList(); + Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); + + while (enumeration.hasMoreElements()) { + NetworkInterface networkInterface = enumeration.nextElement(); + if ("docker0".equals(networkInterface.getName()) || !networkInterface.isUp()) { + continue; + } + Enumeration addrs = networkInterface.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress address = addrs.nextElement(); + if (address.isLoopbackAddress()) { + continue; + } + //ip4 highter priority + if (address instanceof Inet6Address) { + candidatesHost.add(address.getHostAddress()); + continue; + } + return address.getHostAddress(); + } + } + + if (!candidatesHost.isEmpty()) { + return candidatesHost.get(0); + } + return null; + } + public static boolean compareAndIncreaseOnly(final AtomicLong target, final long value) { long prev = target.get(); while (value > prev) { diff --git a/common/src/test/java/org/apache/rocketmq/common/MixAllTest.java b/common/src/test/java/org/apache/rocketmq/common/MixAllTest.java index 218b36d2d8be..5158ce0e6f35 100644 --- a/common/src/test/java/org/apache/rocketmq/common/MixAllTest.java +++ b/common/src/test/java/org/apache/rocketmq/common/MixAllTest.java @@ -20,11 +20,8 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.lang.reflect.Method; import java.net.InetAddress; -import java.nio.ByteOrder; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; @@ -93,4 +90,12 @@ public void testString2File() throws IOException { MixAll.string2File("MixAll_testString2File", fileName); assertThat(MixAll.file2String(fileName)).isEqualTo("MixAll_testString2File"); } + + @Test + public void test_getLocalhostByNetworkInterface() throws Exception { + Method method = MixAll.class.getDeclaredMethod("getLocalhostByNetworkInterface"); + method.setAccessible(true); + Object invoke = method.invoke(null); + assertThat(invoke).isNotNull(); + } }