前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊artemis的NetworkHealthCheck

聊聊artemis的NetworkHealthCheck

原创
作者头像
code4it
修改2020-02-11 10:20:12
2120
修改2020-02-11 10:20:12
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下artemis的NetworkHealthCheck

NetworkHealthCheck

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NetworkHealthCheck
  • check
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档