You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用频繁出现java.net.UnknownHostException DNS解析异常求助

排查与解决Android应用偶发UnknownHostException问题

问题概况

Android应用通过Crashlytics捕获到频繁的非致命java.net.UnknownHostException,仅部分用户受影响,出现时间无规律。部分用户通过重装应用或使用VPN可恢复连接,但Postman等工具能正常访问后端。后端基础路径为http://abc.xyz.in:8080,基于AWS Elastic Beanstalk部署,域名在GoDaddy购买,由Route53负责解析。

异常核心堆栈指向自定义HttpDNS实现:

org.xbill.DNS.Address.lookupHostName (Address.java:272)
org.xbill.DNS.Address.getByName (Address.java:311)
stock.ledger.commons.CustomHttpDns.lookup (CustomHttpDns.kt:62)

排查方向

1. 自定义HttpDNS逻辑缺陷

从堆栈看,异常触发于自定义DNS解析环节,重点检查:

  • 缓存策略:是否存在旧IP缓存未及时更新,导致解析失效?
  • 异常处理:解析失败时是否直接抛异常,未回退到系统默认DNS?
  • 网络适配:是否在特定网络环境(如移动数据、小众运营商)下,自定义DNS服务器不可达?

2. 域名解析链路问题

检查GoDaddy+Route53的解析链路:

  • 域名服务器指向:确认GoDaddy已将域名的DNS服务器完全配置为Route53的权威服务器,避免混合解析异常。
  • Route53 TTL设置:若TTL过长,后端IP变更后客户端缓存无法及时更新;过短则增加解析开销,建议设置为5-15分钟。
  • Route53健康检查:验证是否正确剔除了不健康的后端实例IP,避免返回无效地址。

3. Android系统与网络环境问题

  • 系统DNS缓存:Android系统及应用层面的DNS缓存可能留存失效IP,重装应用会清除应用缓存,VPN会切换DNS服务器,这解释了临时解决方案的有效性。
  • 运营商DNS异常:部分区域的运营商DNS可能存在解析故障,导致特定用户无法正常解析域名。

4. OkHttp配置问题

  • 重试策略:默认RetryAndFollowUpInterceptor不会重试UnknownHostException,需确认是否配置了自定义重试逻辑。
  • DNS fallback:是否强制依赖自定义DNS,未配置系统DNS作为兜底方案?

解决方法

1. 修复自定义HttpDNS实现

添加解析失败回退机制、合理缓存策略及重试逻辑:

class CustomHttpDns : Dns {
    private val dnsCache = mutableMapOf<String, Pair<List<InetAddress>, Long>>()
    private val cacheExpireTime = 10 * 60 * 1000 // 缓存10分钟

    override fun lookup(hostname: String): List<InetAddress> {
        // 优先读取有效缓存
        val cachedEntry = dnsCache[hostname]
        if (cachedEntry != null && System.currentTimeMillis() - cachedEntry.second < cacheExpireTime) {
            return cachedEntry.first
        }

        return try {
            // 自定义DNS解析
            val addresses = Address.getAllByName(hostname).toList()
            dnsCache[hostname] = addresses to System.currentTimeMillis()
            addresses
        } catch (e: UnknownHostException) {
            // 回退到系统默认DNS解析
            InetAddress.getAllByName(hostname).toList()
        }
    }
}

2. 优化域名解析配置

  • 在Route53中将域名记录TTL设置为10分钟,平衡缓存有效性与更新速度。
  • 确认GoDaddy域名的DNS服务器完全指向Route53提供的权威服务器,无残留第三方DNS配置。
  • 开启Route53健康检查,确保仅返回健康的后端实例IP。

3. 处理系统DNS缓存

  • 监听网络连接变化(通过ConnectivityManager.NetworkCallback),在网络切换时清空应用内的DNS缓存。
  • 为用户提供手动刷新DNS缓存的入口(如设置页按钮),快速解决缓存失效问题。

4. 调整OkHttp配置

  • 自定义重试拦截器,针对UnknownHostException进行最多3次递增间隔重试(如1s、2s、4s)。
  • 确保OkHttp的DNS配置中,自定义DNS失效时能自动回退到系统DNS。

5. 增强监控与日志

  • 在CustomHttpDns中添加详细日志,记录解析请求的hostname、网络类型、解析结果、异常信息,便于定位问题场景。
  • 收集异常用户的设备信息(Android版本、运营商、地区),缩小问题范围。

内容的提问来源于stack exchange,提问作者sake007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:40:29