【问题标题】:Java DNS resolution hangs foreverJava DNS 解析永远挂起
【发布时间】:2016-06-23 04:34:38
【问题描述】:

我正在使用 curator 框架连接到 zookeeper 服务器,但遇到了奇怪的 DNS 解析问题。这是线程的 jstack 转储,

#21 prio=5 os_prio=0 tid=0x0000000001888800 nid=0x3a46 runnable [0x00007f25e69f3000]
java.lang.Thread.State: RUNNABLE
    at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at org.apache.zookeeper.client.StaticHostProvider.resolveAndShuffle(StaticHostProvider.java:117)
    at org.apache.zookeeper.client.StaticHostProvider.<init>(StaticHostProvider.java:81)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:1096)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:1006)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:804)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:679)
    at com.netflix.curator.HandleHolder$1.getZooKeeper(HandleHolder.java:72)
    - locked <0x00000000fd761f40> (a com.netflix.curator.HandleHolder$1)
    at com.netflix.curator.HandleHolder.getZooKeeper(HandleHolder.java:46)
    at com.netflix.curator.ConnectionState.reset(ConnectionState.java:122)
    at com.netflix.curator.ConnectionState.start(ConnectionState.java:95)
    at com.netflix.curator.CuratorZookeeperClient.start(CuratorZookeeperClient.java:137)
    at com.netflix.curator.framework.imps.CuratorFrameworkImpl.start(CuratorFrameworkImpl.java:167)

线程似乎卡在本机方法中并且永远不会返回。它也非常随机地发生,因此无法始终如一地重现。有任何想法吗?

【问题讨论】:

  • 不确定是否是 DNS 的问题。
  • 我目前随机遇到同样的问题。我们的 Djava.net.preferIPv4Stack=true 已定义,我们在 RedHat 服务器上运行。我们能否为该 DNS 解析调用定义一个超时时间。

标签: java networking dns apache-zookeeper apache-curator


【解决方案1】:

我们也在努力解决这个问题。看起来这是由于 glibc 错误:https://bugzilla.kernel.org/show_bug.cgi?id=99671 或内核错误:https://bugzilla.redhat.com/show_bug.cgi?id=1209433 取决于你问谁;)

也值得一读:https://access.redhat.com/security/cve/cve-2013-7423https://alas.aws.amazon.com/ALAS-2015-617.html

要确认确实是这种情况,请将 gdb 附加到 java 进程:

gdb --pid <JavaProcessPid>

然后来自 gdb:

info threads 

找到一个执行 recvmsg 的线程:

thread <HangingThreadId>

然后

backtrace 

如果你看到这样的东西,那么你知道 glibc/kernel 升级会有所帮助:

#0  0x00007fc726ff27cd in recvmsg () from /lib64/libc.so.6
#1  0x00007fc727018765 in make_request () from /lib64/libc.so.6
#2  0x00007fc727018b9a in __check_pf () from /lib64/libc.so.6
#3  0x00007fc726fdbd57 in getaddrinfo () from /lib64/libc.so.6
#4  0x00007fc706dd9635 in Java_java_net_Inet6AddressImpl_lookupAllHostAddr () from /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-0.b17.el6_7.x86_64/jre/lib/amd64/libnet.so

更新:看起来内核赢了。详情请看这个帖子:http://www.gossamer-threads.com/lists/linux/kernel/2264958。 还有一个工具可以验证您的系统是否受到内核错误的影响,您可以使用这个简单的程序:https://gist.github.com/stevenschlansker/6ad46c5ccb22bc4f3473

验证:

curl -o pf_dump.c https://gist.githubusercontent.com/stevenschlansker/6ad46c5ccb22bc4f3473/raw/22cfe72f6708de1e3468c1e0fa3888aafae42db4/pf_dump.c
gcc pf_dump.c -pthread -o pf_dump
./pf_dump

如果输出是:

[26170] glibc: check_pf: netlink socket read timeout
Aborted

那么系统就会受到影响。如果输出类似于:

exit success [7618] exit success [7265] exit success

那么系统就ok了。 在 AWS 环境中,使用新内核将 AMI 升级到 (2016.3.2) 似乎已经解决了这个问题。

【讨论】:

  • 请不要写仅链接的答案。要么发表评论,要么在文本中包含重要部分。
  • 是的,glibc 升级解决了这个问题!我忘记更新这个帖子了。
  • 谢谢@Jacek Tomaka。我认为curl -O 应该是curl -o
  • 对于那些具有 AMI 上下文(例如,我使用 2014.03)并发出复制品但上述脚本说“退出成功”的人,这意味着对于那些具有 AMI 的人来说,使用 gist 脚本的检查并不精确。
猜你喜欢
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 2011-09-27
相关资源
最近更新 更多