jvm - UnknowHostException 网络恢复时无法恢复,但重启 JVM 解决了它
问题描述
从某个时间点开始,我们的 JVM(实际上是 Yarn NodeManager)开始报告 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 了;
ENVs:JDK:java版本“1.8.0_121”操作系统:
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
我相信在错误开始发生的时间点,是的,网络有问题。但奇怪的是:
- 为什么网络恢复后无法恢复(例如,当我发现此错误并进行一些测试和 ping 时)。实际上网络问题只发生了 30 分钟,但 JVM 仍然报这些错误;
- 为什么我重新启动JVM后问题就消失了?
我检查了JVM配置,networkaddress.cache.ttl
和networkaddress.cache.negative.ttl
都是默认值;所以,当我们找到未解析的主机名时,我应该重试,网络恢复后应该会成功;
解决方案
您所描述的听起来像是 JVM 缓存了主机名查找。
默认情况下,安装安全管理器时,为了防止 DNS 欺骗攻击,正向主机名解析的结果将被永久缓存。
的默认值networkaddress.cache.ttl
将查找主机名一次并在 JVM 的生命周期内无限期地缓存该结果。尝试将其设置为非默认值——例如,要将 lokoups 缓存 10 秒,请将其设置为“10”。
网络地址.cache.ttl
在 java.security 中指定以指示从名称服务中成功查找名称的缓存策略。该值指定为整数,以指示缓存成功查找的秒数。
-1 值表示“永远缓存”。默认行为是在安装安全管理器时永久缓存,并在未安装安全管理器时缓存实现特定的时间段。
默认networkaddress.cache.negative.ttl
值为 10,但我怀疑这不会影响您的应用程序行为。
推荐阅读
- python - 从空格上的列中删除行
- python - 将数组的每个元素除以另一个数组的每个元素
- node.js - 带有 Babel 和 Typescript 的 Node.js 应用程序中的 ES6 导入语法
- java - NewPooledConnection 泄漏
- c# - 限制对文件夹中文件的 URL 访问 - Azure 上的 ASP.NET MVC
- api - 如何在 Flutter 中将图像从 API 设置为轮播
- c# - 字符串未被识别为有效的日期时间,2019 年 7 月 11 日
- r - 如何按 ID 对行进行分组并计算平均值和 IQR
- node.js - 为项目创建 .env 文件的正确方法
- javascript - 在另一个二维数组中复制洗牌数组的问题