【问题标题】:UnknowHostException cannot recover when network is back but restart JVM solved itUnknownHostException 网络恢复时无法恢复,但重启 JVM 解决了
【发布时间】:2020-04-16 09:48:33
【问题描述】:

从某个时间点开始,我们的 JVM(实际上是 Yarn NodeManager)开始报告 UnknownHostException; 由JVM代码报告

return InetAddress.getByName(host);

接下来的2天多,异常一直存在;在报告此错误期间,我进行了以下测试:

  1. 在错误发生期间,ping 可以成功并获得 IP 地址(很奇怪);
  2. 报错期间,我写了一个简单的测试用例来检查主机名解析,它也可以成功:
  3. 重启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” 操作系统:

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

我相信在错误开始发生的时间点,是的,网络有问题。但奇怪的是:

  1. 为什么网络恢复后无法恢复(例如,当我 发现这个错误并做一些测试和ping)。其实网络 问题只发生了 30 分钟,但 JVM 仍然报告这些 错误;
  2. 为什么重启JVM后问题消失了?

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

【问题讨论】:

    标签: jvm inetaddress unknown-host


    【解决方案1】:

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

    来自Javadoc for InetAddress

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

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

    这是来自Networking Properties的条目:

    networkaddress.cache.ttl

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 2017-11-06
      • 2015-10-08
      相关资源
      最近更新 更多