unknownhostexception本质是dns解析失败导致无法获取ip,需优先排查网络连通性、dns配置、hosts文件格式、java环境限制及容器dns策略。先用nslookup/dig验证dns响应,检查hosts语法与缓存刷新,再确认udp 53端口是否开放,最后按场景决定是否重试。

UnknownHostException 不是连接失败,而是压根没拿到 IP 地址——连建立 TCP 连接的机会都没有。排查要从系统网络层开始,而不是一上来就改 Java 代码。
先确认 DNS 是否真能响应
别只 ping 域名或 IP,得直接测 DNS 解析本身:
- 运行
nslookup api.example.com,看是否返回 A/AAAA 记录;如果显示connection timed out或server can't find,说明 DNS 请求根本没通 - 换公共 DNS 测试:
nslookup api.example.com 8.8.8.8,能通说明本地 DNS(如公司内网 DNS)异常或被策略拦截 - 用
dig example.com +short更简洁地验证解析结果,避免 nslookup 的冗余输出干扰判断
检查 /etc/hosts(或 Windows hosts 文件)格式
hosts 文件优先级高于 DNS,但一行写错就会让整个解析卡住:
- 每行只能是
IPhostname,IP 和域名之间不能有多个空格或不可见字符 - 注释必须独占一行,或写在行尾且
#前有空格;127.0.0.1 localhost#comment是非法的,会被当成主机名localhost#comment去解析 - 改完 hosts 后,Java 不会自动刷新缓存——必须重启 JVM,或调用
InetAddress.clearCache()(JDK 8+ 支持)
验证 Java 进程能否发出 DNS 查询
某些环境会静默阻断 DNS 请求:
- 容器或沙箱中可能禁用了 UDP 53 端口:执行
telnet 8.8.8.8 53,失败说明 DNS 出口被封 - 检查是否设置了
-Dnetworkaddress.cache.ttl=0,它虽禁用缓存,但不会导致解析失败;真正影响的是底层网络策略 - Alpine 基础镜像(musl libc)在 Kubernetes 中常因 DNS 配置缺失抛此异常,需显式挂载
/etc/resolv.conf或设置dnsConfig
区分是临时抖动还是永久错误
重试有意义,但必须看场景:
- 硬编码域名(如
"api.service")首次解析失败,大概率是临时 DNS 抖动,可用指数退避重试 3 次(100ms → 200ms → 400ms) - 用户输入或配置项里的域名,若含空格、下划线、
http://前缀等明显非法字符,应立即拒绝,不重试 - 启动时预解析关键域名并缓存结果(例如用 Caffeine 缓存
InetAddress,TTL 设为 30 秒),比每次请求都解析更稳
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











