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

3 分钟阅读
0

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

简短描述

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

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

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

解决方法

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

确定错误的根本原因

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

来自 dig 或 nslookup 命令的有效应答

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

  • 重启应用程序。
  • 确认您的 Java 应用程序的 DNS 缓存没有损坏。如果可能,请将应用程序配置为遵守 DNS TTL。要使用固定 TTL,请指定 60 秒或更短的时间。有关更多信息,请参阅 Setting the JVM TTL for DNS name lookups

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

$ dig timeout.example.com

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

如果来自 Amazon EC2 实例的 dig 命令显示 no servers could be reached,则验证是否已启用源 VPC 的 DNS 支持选项。有关更多信息,请参阅 Amazon DNS server

在以下示例中,在 VPC 级别禁用 DNS 支持。针对 VPC 解析器(10.1.1.2)的 dig 查询和 talnet 失败,而针对 Cloudflare 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: **注意:**将 domain 替换为您的域。

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 输出显示未创建且未启用 DNSSEC 的 DNS 记录的 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)和路由表的设置。要查看说明,请参阅 How do I troubleshoot Amazon EC2 instance connection timeout errors from the internet?

在此示例中,输出结果的状态为 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 记录不存在于私有托管区中,则该 DNS 记录不会回退到公共托管区,并且会返回 NXDOMAIN

有关更多信息,请参阅 Resolving DNS queries between VPCs and your network

检查是否存在子域委派问题

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

避免出现间歇性 DNS 解析问题

以下是域委派的示例:

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

当孙区域(api.today.example.com)NS 记录存在于父区域(example.com)中时,请确保它也存在于子区域(today.example.com)中。有关更多信息,请参阅 How do I test if my delegated subdomain resolves correctly?

如果间歇性地出现 UnknownHostException 错误,那么原因可能是 Amazon EC2 存在 DNS 限制。此限制为每个网络接口每秒 1,024 个数据包,且限值无法上调。Amazon 提供的 DNS 服务器支持的每秒 DNS 查询数因查询类型、响应大小和协议类型而异。有关更多信息,请参阅 How can I determine whether my DNS queries to the Amazon provided DNS server are failing due to VPC DNS throttling?


AWS 官方
AWS 官方已更新 2 年前