java.net.UnknownHostException异常排查求助:16%用户遇主机解析失败
Hey Anthony,
Looking at your stack trace and code, this issue is clearly tied to DNS resolution failures during OkHttp's connection setup—since it’s failing at InetAddress.lookupHostByName, the core system-level DNS lookup step. With 16% of users affected, this isn’t a universal problem; it’s likely linked to specific network environments, device configurations, or edge cases in your setup. Here are actionable troubleshooting steps to narrow it down:
1. Investigate DNS Server & Network Environment Patterns
- Isolate network-specific issues: 16% of users suggests failures are concentrated in certain ISPs, regions, or users with custom DNS settings (e.g., broken home routers, corporate proxies). Add logging to capture:
- User’s network type (mobile/Wi-Fi)
- Active DNS server addresses (retrieve via Android’s
ConnectivityManageror system properties) - VPN/proxy status (VPNs can route DNS through unreliable servers)
- Test DNS timeout limits: Android’s default DNS lookup has a short timeout (often 15-30s), and OkHttp’s
connectTimeout(60s in your code) includes DNS resolution time. For users in slow network areas, this window might be too tight.
2. Audit Your Interceptor for Hidden Blockages
While the stack trace doesn’t point directly to your interceptor, rule out unintended delays that could eat into the connection timeout:
- Check helper methods for blocking operations: Methods like
HelpUtils.getUserAgent(),HelpUtils.getDeviceID(), orCompatUtils.getLocaleToString()—do they perform disk I/O, hold locks, or rely on slow shared resources? Even a short block could stall the thread before it reaches DNS lookup. - Validate singleton access: Ensure
MyApplication.getInstance().getDataHolder().getUserAccessToken()doesn’t involve synchronized blocks or slow resource fetching that could delay request setup.
3. Tune OkHttp Configuration for Resilience
- Adjust retry policies: OkHttp’s default
RetryAndFollowUpInterceptormay not retry DNS failures aggressively. Extend or replace it to explicitly retry on DNS-relatedIOExceptions. - Force IPv4 (temporary test): Some networks have broken IPv6 support, causing DNS delays. Try forcing OkHttp to use IPv4 only to see if failure rates drop:
httpClient.dns(new Dns() { @Override public List<InetAddress> lookup(String hostname) throws IOException { List<InetAddress> ipv4Addresses = new ArrayList<>(); for (InetAddress addr : InetAddress.getAllByName(hostname)) { if (addr instanceof Inet4Address) { ipv4Addresses.add(addr); } } return ipv4Addresses.isEmpty() ? InetAddress.getAllByName(hostname) : ipv4Addresses; } }); - Extend connect timeout: Temporarily increase
connectTimeoutfrom 60s to 90s to rule out slow DNS resolution as the root cause.
4. Analyze Device & OS Version Trends
- Check for device-specific bugs: Use crash reporting tools to filter failures by Android version (pre-Android 7 devices have known DNS cache issues) or device brand (some manufacturers modify DNS handling).
- Test DNS cache corruption: Some devices may have corrupted DNS caches. While you can’t clear it directly, encouraging affected users to reset network settings can help verify this as a cause.
5. Add Targeted Logging & Monitoring
- Capture failure context: When catching the
IOExceptionfrom Retrofit’sexecute(), log:- Full request URL (confirm it’s resolving to the correct domain)
- Timestamp and device signal strength (if available)
- Use OkHttp Event Listeners: Implement
EventListenerto track DNS lookup duration and success rates across users—this gives granular data on how often DNS fails and how long successful lookups take.
Immediate Mitigation: Fallback DNS Resolver
As a quick test, add a fallback to a reliable public DNS server (e.g., 8.8.8.8) if the user’s default DNS fails:
httpClient.dns(new Dns() { @Override public List<InetAddress> lookup(String hostname) throws IOException { try { // First try system default DNS return Arrays.asList(InetAddress.getAllByName(hostname)); } catch (IOException e) { // Fallback to Google Public DNS return Arrays.asList(InetAddress.getAllByName(hostname, InetAddress.getByName("8.8.8.8"))); } } });
Start with collecting contextual data (network type, DNS servers, device info) to identify patterns, then test the fallback DNS and configuration tweaks. That should help you narrow down the root cause quickly.
内容的提问来源于stack exchange,提问作者anthony

