聊聊artemis的NetworkHealthCheck

编程

NetworkHealthCheck

activemq-artemis-2.11.0/artemis-commons/src/main/java/org/apache/activemq/artemis/core/server/NetworkHealthCheck.java

public class NetworkHealthCheck extends ActiveMQScheduledComponent {

private static final Logger logger = Logger.getLogger(NetworkHealthCheck.class);

private final Set<ActiveMQComponent> componentList = new ConcurrentHashSet<>();

private final Set<InetAddress> addresses = new ConcurrentHashSet<>();

private final Set<URL> urls = new ConcurrentHashSet<>();

private NetworkInterface networkInterface;

public static final String IPV6_DEFAULT_COMMAND = "ping6 -c 1 %2$s";

public static final String IPV4_DEFAULT_COMMAND = "ping -c 1 -t %d %s";

private String ipv4Command = IPV4_DEFAULT_COMMAND;

private String ipv6Command = IPV6_DEFAULT_COMMAND;

// To be used on tests. As we use the loopback as a valid address on tests.

private boolean ignoreLoopback = false;

private boolean ownShutdown = false;

/**

* The timeout to be used on isReachable

*/

private int networkTimeout;

//......

public void run() {

boolean healthy = check();

if (healthy) {

for (ActiveMQComponent component : componentList) {

if (!component.isStarted() && ownShutdown) {

try {

ActiveMQUtilLogger.LOGGER.startingService(component.toString());

component.start();

} catch (Exception e) {

ActiveMQUtilLogger.LOGGER.errorStartingComponent(e, component.toString());

}

}

ownShutdown = false;

}

} else {

for (ActiveMQComponent component : componentList) {

if (component.isStarted()) {

ownShutdown = true;

try {

ActiveMQUtilLogger.LOGGER.stoppingService(component.toString());

component.stop();

} catch (Exception e) {

ActiveMQUtilLogger.LOGGER.errorStoppingComponent(e, component.toString());

}

}

}

}

}

//......

}

  • NetworkHealthCheck继承了ActiveMQScheduledComponent,其run方法先执行check判断是否healthy,之后遍历componentList,对于非healthy的且component.isStarted()为true的更新ownShutdown为true,然后执行component.stop();对于healthy的且component.isStarted()为false以及ownShutdown为true的执行component.start(),最后更新ownShutdown为false

check

activemq-artemis-2.11.0/artemis-commons/src/main/java/org/apache/activemq/artemis/core/server/NetworkHealthCheck.java

public class NetworkHealthCheck extends ActiveMQScheduledComponent {

//......

public boolean check() {

if (isEmpty()) {

return true;

}

for (InetAddress address : addresses) {

if (check(address)) {

return true;

}

}

for (URL url : urls) {

if (check(url)) {

return true;

}

}

return false;

}

public boolean isEmpty() {

return addresses.isEmpty() && urls.isEmpty();

}

public boolean check(InetAddress address) {

if (address == null) {

return false;

}

try {

if (!hasCustomPingCommand() && isReachable(address)) {

if (logger.isTraceEnabled()) {

logger.tracef(address + " OK");

}

return true;

} else {

return purePing(address);

}

} catch (Exception e) {

ActiveMQUtilLogger.LOGGER.failedToCheckAddress(e, address.toString());

return false;

}

}

public boolean hasCustomPingCommand() {

return !getIpv4Command().equals(IPV4_DEFAULT_COMMAND) || !getIpv6Command().equals(IPV6_DEFAULT_COMMAND);

}

protected boolean isReachable(InetAddress address) throws IOException {

return address.isReachable(networkInterface, 0, networkTimeout);

}

public boolean purePing(InetAddress address) throws IOException, InterruptedException {

long timeout = Math.max(1, TimeUnit.MILLISECONDS.toSeconds(networkTimeout));

// it did not work with a simple isReachable, it could be because there"s no root access, so we will try ping executable

if (logger.isTraceEnabled()) {

logger.trace("purePing on canonical address " + address.getCanonicalHostName());

}

ProcessBuilder processBuilder;

if (address instanceof Inet6Address) {

processBuilder = buildProcess(ipv6Command, timeout, address.getCanonicalHostName());

} else {

processBuilder = buildProcess(ipv4Command, timeout, address.getCanonicalHostName());

}

Process pingProcess = processBuilder.start();

readStream(pingProcess.getInputStream(), false);

readStream(pingProcess.getErrorStream(), true);

return pingProcess.waitFor() == 0;

}

public boolean check(URL url) {

if (url == null) {

return false;

}

try {

URLConnection connection = url.openConnection();

connection.setReadTimeout(networkTimeout);

InputStream is = connection.getInputStream();

is.close();

return true;

} catch (Exception e) {

ActiveMQUtilLogger.LOGGER.failedToCheckURL(e, url.toString());

return false;

}

}

//......

}

  • check方法对于addresses且urls为空的返回true,之后遍历addresses及urls挨个执行check;对于InetAddress的check,在hasCustomPingCommand方法返回false且isReachable返回true的情况下返回true,否则使用purePing进行检查;purePing方法使用Process来执行ping;对于url的check,则使用jdk的URLConnection来openConnection,成功返回true,超时或其他异常返回false

小结

NetworkHealthCheck继承了ActiveMQScheduledComponent,其run方法先执行check判断是否healthy,之后遍历componentList,对于非healthy的且component.isStarted()为true的更新ownShutdown为true,然后执行component.stop();对于healthy的且component.isStarted()为false以及ownShutdown为true的执行component.start(),最后更新ownShutdown为false

doc

  • NetworkHealthCheck

以上是 聊聊artemis的NetworkHealthCheck 的全部内容, 来源链接: utcz.com/z/513183.html

回到顶部