全部產品
Search
文件中心

HTTPDNS:Java端HTTPDNS+OkHttp最佳實務

更新時間:Jan 10, 2026

本文檔介紹在 Java 應用中使用 OkHttp 接入 HTTPDNS 的方案。

1. 背景說明

如果您在 Java 端使用的網路架構是 OkHttp,通過調用 OkHttp 提供的自訂 DNS 服務介面,可以簡潔優雅地使用 HTTPDNS 的服務。

OkHttp 是一個處理網路請求的開源專案,是 Java/Android 端最火熱的輕量級架構,由移動支付 Square 公司貢獻。隨著 OkHttp 的不斷成熟,越來越多的開發人員使用 OkHttp 作為網路架構。

OkHttp 預設使用系統 DNS 服務 InetAddress 進行網域名稱解析,同時也暴露了自訂 DNS 服務的介面,通過該介面我們可以優雅地使用 HTTPDNS。

2. 實現自訂 DNS 介面

OkHttp 暴露了 Dns 介面,通過實現該介面可以自訂 DNS 服務:

import com.alibaba.sdk.java.httpdns.HTTPDNSResult;
import com.alibaba.sdk.java.httpdns.HttpDnsClient;
import com.alibaba.sdk.java.httpdns.RequestIpType;
import okhttp3.Dns;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class OkHttpDns implements Dns {
    
    private final HttpDnsClient httpDnsClient;
    
    public OkHttpDns(HttpDnsClient httpDnsClient) {
        this.httpDnsClient = httpDnsClient;
    }
    
    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        HTTPDNSResult result = httpDnsClient.getHttpDnsResultForHostSyncNonBlocking(
            hostname, 
            RequestIpType.both
        );
        
        List<InetAddress> inetAddresses = new ArrayList<>();
        
        try {
            if (result != null && result.getIps() != null) {
                for (String ip : result.getIps()) {
                    inetAddresses.add(InetAddress.getByName(ip));
                }
            }
            if (result != null && result.getIpv6s() != null) {
                for (String ip : result.getIpv6s()) {
                    inetAddresses.add(InetAddress.getByName(ip));
                }
            }
        } catch (UnknownHostException e) {
            // 忽略單個 IP 解析失敗
        }
        
        if (!inetAddresses.isEmpty()) {
            return inetAddresses;
        }
        
        // 降級到系統 DNS
        return Dns.SYSTEM.lookup(hostname);
    }
}

由於 OkHttp 內部有重試機制,重試時可能會選擇不同的 IP 建立串連,所以在 lookup() 方法中返回包含多個 IP 的列表,可以有效避免單一 IP 不可用導致請求失敗的情況。

3. 配置 OkHttpClient

建立 OkHttpClient 對象,傳入自訂 DNS 服務:

HttpDnsClient httpDnsClient = HttpDnsClient.getClient(accountId);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .dns(new OkHttpDns(httpDnsClient))
    .build();

4. 總結

OkHttp + HTTPDNS 的主要優勢:

  • 實現簡單:只需實現 Dns 介面即可接入

  • 通用性強:在 HTTPS、SNI 以及設定 Cookie 等情境均適用,無需額外處理認證校正、網域名稱檢查等環節

  • 自動重試:返回多個 IP 時,OkHttp 會自動嘗試不同的 IP 建立串連