Skip to content

Commit

Permalink
[ISSUE alibaba#8515] Optimize some code in InetUtils (alibaba#8522)
Browse files Browse the repository at this point in the history
* [ISSUE alibaba#8515] auto refresh ip address

Close alibaba#8515

* [ISSUE alibaba#8515] add the unit test

Close alibaba#8515

* [ISSUE alibaba#8515] clean system variable after unit test done

Close alibaba#8515

* [ISSUE alibaba#8515] add tearDown method for the unit test

- reformat by nacos-style

* [ISSUE alibaba#8515] fix ci error

* [ISSUE alibaba#8515] fix ci error

* [ISSUE alibaba#8515] fix ci error
  • Loading branch information
onewe authored Jun 20, 2022
1 parent 7a3757c commit cbda95d
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 59 deletions.
1 change: 1 addition & 0 deletions sys/src/main/java/com/alibaba/nacos/sys/env/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public interface Constants {
String USE_ONLY_SITE_INTERFACES = "nacos.inetutils.use-only-site-local-interfaces";
String PREFERRED_NETWORKS = "nacos.inetutils.preferred-networks";
String IGNORED_INTERFACES = "nacos.inetutils.ignored-interfaces";
String AUTO_REFRESH_TIME = "nacos.core.inet.auto-refresh";
String IP_ADDRESS = "nacos.inetutils.ip-address";
String PREFER_HOSTNAME_OVER_IP = "nacos.inetutils.prefer-hostname-over-ip";
String SYSTEM_PREFER_HOSTNAME_OVER_IP = "nacos.preferHostnameOverIp";
Expand Down
162 changes: 105 additions & 57 deletions sys/src/main/java/com/alibaba/nacos/sys/utils/InetUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.alibaba.nacos.sys.utils;

import com.alibaba.nacos.common.executor.ExecutorFactory;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.SlowEvent;
import com.alibaba.nacos.common.utils.InternetAddressUtil;
Expand All @@ -35,6 +37,8 @@
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.alibaba.nacos.sys.env.Constants.IP_ADDRESS;
import static com.alibaba.nacos.sys.env.Constants.NACOS_SERVER_IP;
Expand All @@ -51,15 +55,18 @@ public class InetUtils {

private static final Logger LOG = LoggerFactory.getLogger(InetUtils.class);

private static String selfIP;
private static final List<String> PREFERRED_NETWORKS = new ArrayList<>();

private static boolean useOnlySiteLocalInterface = false;
private static final List<String> IGNORED_INTERFACES = new ArrayList<>();

private static boolean preferHostnameOverIP = false;
private static final ScheduledExecutorService INET_AUTO_REFRESH_EXECUTOR = ExecutorFactory.Managed.newSingleScheduledExecutorService(
InetUtils.class.getCanonicalName(), new NameThreadFactory("com.alibaba.inet.ip.auto-refresh"));

private static final List<String> PREFERRED_NETWORKS = new ArrayList<String>();
private static volatile String selfIP;

private static final List<String> IGNORED_INTERFACES = new ArrayList<String>();
private static boolean useOnlySiteLocalInterface = false;

private static boolean preferHostnameOverIP = false;

static {
NotifyCenter.registerToSharePublisher(IPChangeEvent.class);
Expand All @@ -72,60 +79,100 @@ public class InetUtils {
List<String> interfaces = EnvUtil.getPropertyList(Constants.IGNORED_INTERFACES);
IGNORED_INTERFACES.addAll(interfaces);

final long delayMs = Long.getLong("nacos.core.inet.auto-refresh", 30_000L);
refreshIp();

Runnable ipAutoRefresh = () -> {
String nacosIP = System.getProperty(NACOS_SERVER_IP);
if (StringUtils.isBlank(nacosIP)) {
nacosIP = EnvUtil.getProperty(IP_ADDRESS);
}
if (!StringUtils.isBlank(nacosIP)) {
if (!(InternetAddressUtil.isIP(nacosIP) || InternetAddressUtil.isDomain(nacosIP))) {
throw new RuntimeException("nacos address " + nacosIP + " is not ip");
}
}
String tmpSelfIP = nacosIP;
if (StringUtils.isBlank(tmpSelfIP)) {
preferHostnameOverIP = Boolean.getBoolean(SYSTEM_PREFER_HOSTNAME_OVER_IP);

if (!preferHostnameOverIP) {
preferHostnameOverIP = Boolean.parseBoolean(EnvUtil.getProperty(PREFER_HOSTNAME_OVER_IP));
}

if (preferHostnameOverIP) {
InetAddress inetAddress;
try {
inetAddress = InetAddress.getLocalHost();
if (inetAddress.getHostName().equals(inetAddress.getCanonicalHostName())) {
tmpSelfIP = inetAddress.getHostName();
} else {
tmpSelfIP = inetAddress.getCanonicalHostName();
}
} catch (UnknownHostException ignore) {
LOG.warn("Unable to retrieve localhost");
}
} else {
tmpSelfIP = Objects.requireNonNull(findFirstNonLoopbackAddress()).getHostAddress();
}
final long delayMs = Long.getLong(Constants.AUTO_REFRESH_TIME, 30_000L);

INET_AUTO_REFRESH_EXECUTOR.scheduleAtFixedRate(() -> {
try {
InetUtils.refreshIp();
} catch (Exception e) {
LOG.error("refresh ip error", e);
}
if (InternetAddressUtil.PREFER_IPV6_ADDRESSES && !tmpSelfIP.startsWith(InternetAddressUtil.IPV6_START_MARK) && !tmpSelfIP
.endsWith(InternetAddressUtil.IPV6_END_MARK)) {
tmpSelfIP = InternetAddressUtil.IPV6_START_MARK + tmpSelfIP + InternetAddressUtil.IPV6_END_MARK;
if (StringUtils.contains(tmpSelfIP, InternetAddressUtil.PERCENT_SIGN_IN_IPV6)) {
tmpSelfIP = tmpSelfIP.substring(0, tmpSelfIP.indexOf(InternetAddressUtil.PERCENT_SIGN_IN_IPV6))
+ InternetAddressUtil.IPV6_END_MARK;
}
}, delayMs, delayMs, TimeUnit.MILLISECONDS);
}

/**
* refresh ip address.
*/
private static void refreshIp() {

String tmpSelfIp = getNacosIp();

if (StringUtils.isBlank(tmpSelfIp)) {
tmpSelfIp = getPreferHostnameOverIP();
}

if (StringUtils.isBlank(tmpSelfIp)) {
tmpSelfIp = Objects.requireNonNull(findFirstNonLoopbackAddress()).getHostAddress();
}

if (InternetAddressUtil.PREFER_IPV6_ADDRESSES && !tmpSelfIp.startsWith(InternetAddressUtil.IPV6_START_MARK)
&& !tmpSelfIp.endsWith(InternetAddressUtil.IPV6_END_MARK)) {
tmpSelfIp = InternetAddressUtil.IPV6_START_MARK + tmpSelfIp + InternetAddressUtil.IPV6_END_MARK;
if (StringUtils.contains(tmpSelfIp, InternetAddressUtil.PERCENT_SIGN_IN_IPV6)) {
tmpSelfIp = tmpSelfIp.substring(0, tmpSelfIp.indexOf(InternetAddressUtil.PERCENT_SIGN_IN_IPV6))
+ InternetAddressUtil.IPV6_END_MARK;
}
if (!Objects.equals(selfIP, tmpSelfIP) && Objects.nonNull(selfIP)) {
IPChangeEvent event = new IPChangeEvent();
event.setOldIP(selfIP);
event.setNewIP(tmpSelfIP);
NotifyCenter.publishEvent(event);
}
if (!Objects.equals(selfIP, tmpSelfIp) && Objects.nonNull(selfIP)) {
IPChangeEvent event = new IPChangeEvent();
event.setOldIP(selfIP);
event.setNewIP(tmpSelfIp);
NotifyCenter.publishEvent(event);
}
selfIP = tmpSelfIp;
}

/**
* Get ip address from environment
* System property nacos.server.ip
* Spring property nacos.inetutils.ip-address.
*
* @return ip address
*/
private static String getNacosIp() {
String nacosIp = System.getProperty(NACOS_SERVER_IP);
if (StringUtils.isBlank(nacosIp)) {
nacosIp = EnvUtil.getProperty(IP_ADDRESS);
}
if (!StringUtils.isBlank(nacosIp)) {
if (!(InternetAddressUtil.isIP(nacosIp) || InternetAddressUtil.isDomain(nacosIp))) {
throw new RuntimeException("nacos address " + nacosIp + " is not ip");
}
selfIP = tmpSelfIP;
};
}

return nacosIp;
}

/**
* Get ip address.
*
* @return ip address
*/
private static String getPreferHostnameOverIP() {
preferHostnameOverIP = Boolean.getBoolean(SYSTEM_PREFER_HOSTNAME_OVER_IP);

if (!preferHostnameOverIP) {
preferHostnameOverIP = Boolean.parseBoolean(EnvUtil.getProperty(PREFER_HOSTNAME_OVER_IP));
}

ipAutoRefresh.run();
if (!preferHostnameOverIP) {
return null;
}
String preferHostnameOverIp = null;
InetAddress inetAddress;
try {
inetAddress = InetAddress.getLocalHost();
if (inetAddress.getHostName().equals(inetAddress.getCanonicalHostName())) {
preferHostnameOverIp = inetAddress.getHostName();
} else {
preferHostnameOverIp = inetAddress.getCanonicalHostName();
}
} catch (UnknownHostException ignore) {
LOG.warn("Unable to retrieve localhost");
}
return preferHostnameOverIp;
}

public static String getSelfIP() {
Expand Down Expand Up @@ -156,8 +203,9 @@ public static InetAddress findFirstNonLoopbackAddress() {
if (!ignoreInterface(ifc.getDisplayName())) {
for (Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements(); ) {
InetAddress address = addrs.nextElement();
boolean isLegalIpVersion = InternetAddressUtil.PREFER_IPV6_ADDRESSES ? address instanceof Inet6Address
: address instanceof Inet4Address;
boolean isLegalIpVersion =
InternetAddressUtil.PREFER_IPV6_ADDRESSES ? address instanceof Inet6Address
: address instanceof Inet4Address;
if (isLegalIpVersion && !address.isLoopbackAddress() && isPreferredAddress(address)) {
LOG.debug("Found non-loopback interface: " + ifc.getDisplayName());
result = address;
Expand All @@ -177,7 +225,7 @@ public static InetAddress findFirstNonLoopbackAddress() {
try {
return InetAddress.getLocalHost();
} catch (UnknownHostException e) {
LOG.warn("Unable to retrieve localhost");
LOG.error("Unable to retrieve localhost", e);
}

return null;
Expand Down
35 changes: 33 additions & 2 deletions sys/src/test/java/com/alibaba/nacos/sys/utils/InetUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,45 @@

package com.alibaba.nacos.sys.utils;

import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.sys.env.Constants;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.springframework.core.env.StandardEnvironment;
import org.junit.Test;
import org.springframework.mock.env.MockEnvironment;

import java.util.concurrent.TimeUnit;

import static com.alibaba.nacos.sys.env.Constants.NACOS_SERVER_IP;

public class InetUtilsTest {

@Before
public void setUp() {
EnvUtil.setEnvironment(new StandardEnvironment());
EnvUtil.setEnvironment(new MockEnvironment());
}

@Test
public void testRefreshIp() throws InterruptedException {
System.setProperty(NACOS_SERVER_IP, "1.1.1.1");
System.setProperty(Constants.AUTO_REFRESH_TIME, "100");
String selfIP = InetUtils.getSelfIP();
Assert.assertTrue(StringUtils.equalsIgnoreCase(selfIP, "1.1.1.1"));

System.setProperty(NACOS_SERVER_IP, "1.1.1.2");
TimeUnit.MILLISECONDS.sleep(500L);

selfIP = InetUtils.getSelfIP();
Assert.assertTrue(StringUtils.equalsIgnoreCase(selfIP, "1.1.1.2"));

}

@After
public void tearDown() {
System.clearProperty(NACOS_SERVER_IP);
System.clearProperty(Constants.AUTO_REFRESH_TIME);
}

}

0 comments on commit cbda95d

Please sign in to comment.