如何通过OkHttp缩短DNS查询耗时?已检测到DNS阶段耗时约5秒
Nice work pinpointing the DNS lookup as the root cause of your slow requests—5 seconds is way beyond what's normal for that stage. Let's walk through practical, actionable fixes to cut down that DNS latency in OkHttp:
1. Add DNS Caching to OkHttp
OkHttp's default Dns.SYSTEM implementation doesn't cache DNS results, which means every request triggers a fresh lookup even for the same hostname. Adding a simple cache will eliminate redundant DNS calls and drastically speed up repeat requests.
Here's how to implement an LRU-based DNS cache:
private static final Dns CACHING_DNS = new Dns() { // Cache up to 100 hostnames, adjust size based on your needs private final LruCache<String, List<InetAddress>> dnsCache = new LruCache<>(100); private final Dns systemDns = Dns.SYSTEM; @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { // Check cache first List<InetAddress> cachedAddresses = dnsCache.get(hostname); if (cachedAddresses != null) { return cachedAddresses; } // Fall back to system DNS if not cached List<InetAddress> freshAddresses = systemDns.lookup(hostname); dnsCache.put(hostname, freshAddresses); return freshAddresses; } };
Then attach this custom DNS to your OkHttpClient:
OkHttpClient client = new OkHttpClient.Builder() .dns(CACHING_DNS) // ... other configurations .build();
2. Switch to a Faster Public DNS Server
Your system's default DNS server might be slow or have high latency. Replacing it with a reliable public DNS provider (like Cloudflare, Google, or Alibaba) can cut down lookup times significantly.
To use a custom DNS server, you'll need a library like dnsjava (since Java's built-in DNS resolution doesn't let you specify a server directly). Here's a quick example using dnsjava to query Cloudflare's DNS (1.1.1.1):
First add the dependency (for Gradle):
implementation 'dnsjava:dnsjava:3.5.2'
Then implement the custom DNS:
private static final Dns CLOUDFLARE_DNS = new Dns() { @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { try { Record[] records = new Lookup(hostname, Type.A).run(); if (records == null) throw new UnknownHostException("No DNS records found for " + hostname); List<InetAddress> addresses = new ArrayList<>(); for (Record record : records) { if (record instanceof ARecord) { addresses.add(((ARecord) record).getAddress()); } } return addresses; } catch (TextParseException e) { throw new UnknownHostException(e.getMessage()); } } };
Don't forget to set this DNS on your OkHttpClient builder as shown before.
3. Pre-Resolve Critical Hostnames
For domains you know your app will frequently access, pre-resolve their DNS records during app startup or idle periods. This way, when the actual request is made, the DNS result is already cached and ready to use.
Example of pre-resolving in your Application class:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); // Pre-resolve your critical hostnames new Thread(() -> { try { InetAddress.getAllByName("your-api-domain.com"); } catch (UnknownHostException e) { // Handle exception gracefully } }).start(); } }
4. Optimize Connection Pool Settings
While this doesn't directly speed up DNS lookups, a well-configured connection pool will reuse existing connections, which means you won't need to perform DNS lookups as often.
Adjust your OkHttp connection pool to keep connections alive longer and allow more concurrent connections:
ConnectionPool connectionPool = new ConnectionPool( 10, // Max idle connections 30, TimeUnit.MINUTES, // Keep alive duration TimeUnit.MILLISECONDS ); OkHttpClient client = new OkHttpClient.Builder() .connectionPool(connectionPool) // ... other configurations .build();
5. Verify Network Environment
Sometimes DNS latency is caused by external factors:
- Weak mobile network signal or congested Wi-Fi
- VPN or proxy services adding extra routing delays
- Network restrictions blocking certain DNS servers
Test your app on different networks to rule out environmental issues.
Start with DNS caching and switching to a faster DNS server—these two changes will usually give you the biggest improvements in DNS latency.
内容的提问来源于stack exchange,提问作者shmakova

