当网络恢复时,UnknowHostException无法恢复,但重启JVM解决了它

当网络恢复时,UnknowHostException无法恢复,但重启JVM解决了它,jvm,inetaddress,unknown-host,Jvm,Inetaddress,Unknown Host,从一个时间点开始,我们的JVM(实际上是一个纱线节点管理器)开始报告UnknownHostException; 它由JVM代码报告 return InetAddress.getByName(host); 在接下来的2天以上,异常始终存在;在报告此错误期间,我执行以下测试: 在错误发生期间,ping可以成功获得IP地址(非常奇怪) 在出错期间,我编写了一个简单的测试用例来检查主机名解析,它也可能成功: 重启JVM后,错误消失了 这是我用于测试的代码: public class Main {

从一个时间点开始,我们的JVM(实际上是一个纱线节点管理器)开始报告UnknownHostException; 它由JVM代码报告

return InetAddress.getByName(host);
在接下来的2天以上,异常始终存在;在报告此错误期间,我执行以下测试:

  • 在错误发生期间,ping可以成功获得IP地址(非常奇怪)
  • 在出错期间,我编写了一个简单的测试用例来检查主机名解析,它也可能成功:
  • 重启JVM后,错误消失了 这是我用于测试的代码:

    public class Main {
      public static void main(String[] args){
        InetSocketAddress addr = NetUtils.createSocketAddr("host-name:8020");
        System.out.println(addr.isUnresolved());
      }
    }
    
    
    
    
    # NetUtils is a YARN class which simply call the InetAddress.getByName()
        public static InetSocketAddress createSocketAddrForHost(String host, int port) {
            String staticHost = getStaticResolution(host);
            String resolveHost = (staticHost != null) ? staticHost : host;
    
            InetSocketAddress addr;
            try {
              InetAddress iaddr = SecurityUtil.getByName(resolveHost);
              // if there is a static entry for the host, make the returned
              // address look like the original given host
              if (staticHost != null) {
                iaddr = InetAddress.getByAddress(host, iaddr.getAddress());
              }
              addr = new InetSocketAddress(iaddr, port);
            } catch (UnknownHostException e) {
              addr = InetSocketAddress.createUnresolved(host, port);
            }
            return addr;
          }
    
    我们已经很长时间没有更改/etc/hosts了

    环境: JDK:java版本“1.8.0_121” 操作系统:

    我相信在错误开始出现的时间点,是的,网络出现了一些问题。但奇怪的是:

  • 为什么网络恢复后无法恢复(例如,当 找到此错误并执行一些测试和ping)。实际上是网络 问题只发生了30分钟,但JVM仍然报告这些问题 错误
  • 为什么重启JVM后问题就消失了

  • 我检查了JVM配置,
    networkaddress.cache.ttl
    networkaddress.cache.negative.ttl
    都是默认值;因此,当我们找到未解析的主机名时,我应该重试,并在网络恢复后成功

    您所描述的内容听起来像是JVM缓存了主机名查找

    发件人:

    默认情况下,安装安全管理器时,为了防止DNS欺骗攻击,将永久缓存主机名解析的结果

    的默认值将查找一次主机名,并在JVM的生命周期内无限期地缓存结果。尝试将其设置为非默认值–例如,要将lokoups缓存10秒,请将其设置为“10”

    以下是来自:

    networkaddress.cache.ttl

    在java.security中指定,以指示从名称服务成功查找名称的缓存策略。该值被指定为整数,以指示缓存成功查找的秒数

    值-1表示“永久缓存”。默认行为是在安装安全管理器时永久缓存,在未安装安全管理器时缓存特定于实现的一段时间

    networkaddress.cache.negative.ttl的默认值是10,但我怀疑这不会影响您的应用程序行为

    Distributor ID: Ubuntu
    Description:    Ubuntu 14.04.5 LTS
    Release:    14.04
    Codename:   trusty