如何排查我的 Java 应用程序中的 UnknownHostException 错误?

上次更新日期:2022 年 6 月 14 日

如何排查我的 Java 应用程序中的 UnknownHostException 错误?

简短描述

UnknownHostException 是 Java 应用程序中的常见错误消息。此错误通常表示 DNS 解析失败。如果 Java 应用程序无法获得有效的 DNS 应答,则可能会引发 UnknownHostException 错误。

除了 DNS 问题之外,此错误的根本原因可能是:

  • 影响 DNS 解析的软件问题
  • 驱动程序问题
  • Amazon Elastic Compute Cloud (Amazon EC2) 实例中的网络中断

解决方法

注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时遇到错误,请确保您使用的是最新版的 AWS CLI

确定错误的根本原因

  1. 使用 Windows 远程桌面协议 (RDP) 或安全外壳 (SSH) 协议连接托管您的 Java 应用程序的服务器。
  2. 对导致错误的 DNS 名称运行 dig 命令(Linux)或 nslookup 命令(Windows)。
  3. 根据输出,查看以下场景:

dig 或 nslookup 命令的有效答案

如果您从 dignslookup 命令获得有效答案,则可能会出现应用程序级别问题,但在 Java 应用程序中继续收到 UnknownHostException 错误。要解决应用程序级问题,请尝试以下方法:

  • 重新启动应用程序。
  • 确认您的 Java 应用程序不包含错误的 DNS 缓存。如果可能,请将应用程序配置为遵守 DNS TTL。要使用固定 TTL,请指定 60 秒或更短的时间。有关更多信息,请参阅为 DNS 名称查找设置 JVM TTL

在此示例中,服务器或 DNS 解析器存在联网问题。应用程序无法连接,然后超时:

$ dig timeout.example.com

;; global options: +cmd
;; connection timed out; no servers could be reached

如果来自 Amazon EC2 实例的 dig 命令显示无法访问任何服务器,请验证源 VPC 的 DNS 支持选项是否已启用。有关更多信息,请参阅 Amazon DNS 服务器

在以下示例中,在 VPC 级别禁用 DNS 支持。针对 VPC 解析器 (10.1.1.2) 的 dig 查询和 telnet 失败,而针对 cloud-flare DNS 服务器 (1.1.1.1) 的 dig 正在解析。

$ dig google.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> google.com
;; global options: +cmd
;; connection timed out; no servers could be reached

$ telnet 10.1.1.2 53
Trying 10.1.1.2...
telnet:connect to address 10.1.1.2: No route to host

$ dig google.com @1.1.1.1 +short
142.251.16.102
142.251.16.139
142.251.16.138
142.251.16.113
142.251.16.101
142.251.16.100

有效的 NOERROR 响应,缺少有效答案部分

这种情况通常发生在存在地理位置路由策略,但记录不包含服务器地理位置的 DNS 应答时。您可以创建记录并定义地理位置记录,也可以创建默认记录。

以下是此场景的示例输出:

$ dig noanswer.example.com

;; ->>HEADER<<- opcode: QUERY, <b>status: NOERROR</b>, id: 49948
;; flags: qr rd ra; QUERY: 1,
    ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
example.com.   
    300    IN    SOA    ns1.example.com. ns2.example.com. 1 7200 900 1209600 86400

此外,如果 DNS 记录不是在公共托管区域中创建的,并且域名系统安全扩展 (DNSSEC) 已打开,则返回 NOERROR-NOANSWER,而非 NXDOMAIN

要验证 DNSSEC 的状态,请运行以下 dig 命令以显示 NSEC:注意:替换为您的域。

dig <domain> +trace

输出应类似于:

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.co.uk
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43917
;; flags: qr rd ra; QUERY: 1, ANSWER:0, AUTHORITY: 1, ADDITIONAL: 1
;; AUTHORITY SECTION:
example.co.uk. 300 IN SOA ns-1578.awsdns-05.co.uk. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

在以下示例中,dig 输出显示了未创建DNS 记录且未开启 DNSSEC 的 NXDOMAIN

$ dig example.amazon.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>>
    example.amazon.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 64351
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; AUTHORITY SECTION:
amazon.com. 24 IN SOA dns-external-master.amazon.com. root.amazon.com. 2010158906 180 60 3024000 60

NXDOMAIN 或 NOERROR(没有答案)响应

检查您的 DNS 公共托管区以确认 DNS 记录配置正确。

SERVFAIL 状态

-或者-

无法连接到 DNS 解析器或服务器

如果您将 Amazon EC2 实例用于 Java 应用程序,则网络中断很少见,但可能会发生。dignslookup 响应将显示您反复无法连接到 DNS 解析器或服务器。在此情况下,检查您的 AWS 区域中有无任何活动的网络中断

如果您使用的是通过 Route 53 解析器端点连接到 Route 53 私有托管区域的本地服务器,请检查 VPC 上的端点的配置。查看安全组、网络访问控制列表(网络 ACL)和路由表的设置。如何排查来自互联网的 Amazon EC2 实例连接超时错误?

在此情况下,输出具有 SERVFAIL 状态:

$ dig servfail.example.com

;; ->>HEADER<<- opcode: QUERY, <b>status: SERVFAIL</b>, id: 57632
;; flags: qr rd ra;
    QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

检查私有托管区和解析程序规则是否与源 VPC 关联

Amazon 提供的 DNS 解析程序按以下优先级顺序评估最具体的匹配:

  1. 解析器规则
  2. 私有托管区
  3. 公共托管区

如果 DNS 查询与解析器规则匹配,则确认目标 IP 地址是否正在回复正确答案。如果您使用的是私有托管区,请确保已在私有托管区中创建 DNS 记录。如果 DNS 记录不在私有托管区中,则它不会回退到公共托管区及返回 NXDOMAIN

有关更多信息,请参阅解析 VPC 与您的网络之间的 DNS 查询

检查子域委托问题

验证在父区域、子区域和孙区域之间是否已创建正确的子域委托。如果父区域中存在孙区域名称服务器 (NS) 但子区域中缺少,则预计会出现间歇性 NXDOMAIN。每个子区域 NS 记录都必须存在于其父托管区中。

避免间歇性的 DNS 解析问题

以下是域委托的示例:

  • 父区域:example.com
  • 子区域:today.example.com
  • 孙区域:api.today.example.com

当孙区域 (api.today.example.com) NS 记录存在于父区域 (example.com) 中时,请确保它也存在于子区域 (today.example.com) 中。有关更多信息,请参阅如何测试我的委托子域名解析是否正确?

如果您间歇性地收到 UnknownHostException 错误,则 Amazon EC2 DNS 限制可能是一个因素。限制为每个网络接口每秒 1024 个数据包,且这个限制不能提高。Amazon 提供的 DNS 服务器支持的每秒 DNS 查询数因查询类型、响应大小和协议类型而异。有关更多信息,请参阅如何确定对 Amazon 提供的 DNS 服务器的 DNS 查询是否由于 VPC DNS 节流而失败?


这篇文章对您有帮助吗?


您是否需要账单或技术支持?