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

如何通过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:

Fixes to Reduce 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:15:18