全部產品
Search
文件中心

HTTPDNS:Android SDK接入

更新時間:Jul 13, 2024

本章節介紹了HTTPDNS Android SDK的接入方法。

前提條件

  • 如果要手動整合,需要下載SDK包,最新版本為V2.3.0-intl

範例代碼

  • HTTPDNS Android SDK全新Demo工程,請參見HTTPDNS Android Demo,新Demo工程使用Kotlin + MVVM開發,涵蓋了SDK各項功能,包含了最佳實務,開發人員可通過新Demo更快速瞭解如何使用HTTPDNS。

  • SDK已開源,如有特殊需求,可以自行更改源碼進行使用,請參見httpdns-android-sdk

整合步驟

配置SDK的Maven倉庫地址

7.0以下版本

開啟專案根目錄的build.gradle檔案,在allprojectsrepositories中添加Maven倉庫地址:

allprojects {
    repositories {
        maven {
            url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
        }
    }
}

7.0以上版本

開啟專案根目錄的settings.gradle檔案,在dependencyResolutionManagementrepositores中添加Maven倉庫地址

dependencyResolutionManagement {
  repositories {
    maven {
      url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
      name 'aliyun'
      //一定要添加這個配置
      allowInsecureProtocol = true 
    }
  }

添加SDK依賴

開啟應用模組下的build.gradle檔案,在dependencies中添加SDK依賴

dependencies {
    compile 'com.aliyun.ams:alicloud-android-httpdns:2.3.0-intl'
}

配置SDK

混淆配置

如果您的專案中使用Proguard等工具做了代碼混淆,請保留以下配置:

-keep class com.aliyun.ams.ipdetector.Inet64Util{*;}
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}

SDK初始化

擷取服務執行個體

HTTPDNS Android SDK以全域service執行個體的方式提供網域名稱解析服務,您可以通過以下方式擷取執行個體。

  1. 普通方式

    HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID);
    // 參數applicationContext是您Android App的Context
    // 參數accountID是系統分配的Account ID,當您開通HTTPDNS後,您可以在控制台擷取到您對應的Account ID資訊
  2. 鑒權方式

    說明
    • HTTPDNS SDK V1.1.3及以上版本支援鑒權方式,該方式需要在HTTPDNS控制台進行關閉非鑒權介面(請謹慎操作)詳情請參見鑒權解析介面

    • 鑒權預設到期時間為10分鐘。

    • 為避免在日誌中泄漏參數accountID/secretKey或App運行過程中產生的資料,建議線上版本關閉SDK調試日誌。

    • 由於所有使用者使用統一的SDK接入,在接入過程中需要在代碼中設accountID/secretKey參數,而此類參數與計量計費密切相關,為防止惡意反編譯擷取參數造成資訊洩漏,建議您開啟混淆,並進行App加固後再發布上線。

    HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID, secretKey);
    // 參數applicationContext是您Android App的Context
    // 參數accountID是系統分配的Account ID,當您開通HTTPDNS後,您可以在控制台擷取到您對應的Account ID資訊
    // 參數secretKey是鑒權對應的secretKey

初始化佈建服務(可選,2.2.1版本開始支援)

在擷取服務執行個體之後,我們可以通過初始化配置,設定服務的一些屬性,避免服務以預設配置運行。建議進行初始化配置,避免單獨調用API產生的時序問題。不進行初始化配置,也不影響基礎功能使用。此處是程式碼範例,參數說明請查看初始化配置

        // 初始化配置,調用即可,不必處理傳回值。
        new InitConfig.Builder()
                // 配置初始的region
                .setRegion(currentRegion)
                // 配置是否啟用https,預設http
                .setEnableHttps(enableHttps)
                // 佈建服務請求的逾時時間長度,毫秒
                .setTimeout(10 * 1000)
                // 配置是否啟用本機快取,預設不啟用
                .setEnableCacheIp(true)
                // 配置是否允許返回到期IP,預設允許
                .setEnableExpiredIp(true)
                // 配置ipv4探測網域名稱
                .setIpProbeItems(list)
                // 配置介面來自訂緩衝的ttl時間
                .configCacheTtlChanger(ttlChanger)
                // 配置固定IP的網域名稱列表,最佳化SDK的內部邏輯,減少解析頻次
                .configHostWithFixedIp(hostListWithFixedIp)
                // 針對哪一個account配置
                .buildFor(accountID);

設定預解析網域名稱

在您初始化程式時,可以選擇性地預先向HTTPDNS SDK中註冊您後續可能會使用到的網域名稱,以便SDK提前解析,減少後續解析網域名稱時請求的時延。

您只需調用以下介面:

ArrayList<String> hostList = new ArrayList<>(Arrays.asList("www.taobao.com", "www.aliyun.com"));
httpdns.setPreResolveHosts(hostList);
重要

預解析介面設定的同時會觸發非同步網路請求,應該在代碼邏輯上確保調用預解析介面時,已經進行了必備的初始化設定。比如setHTTPSRequestEnabled: 需要在預解析介面之前調用,否則會導致預解析的相關IP採用HTTP請求。

注意事項

  1. 務必編寫降級代碼

    降級代碼指的是HTTPDNS無法擷取期望結果時的處理代碼。請參見設定降級策略相關介面

  2. 記錄從HTTPDNS擷取的IP及sessionId

    我們提供了用於解析問題排查的解決方案,需要您將從HTTPDNS擷取的IP及sessionId記錄到日誌中,詳情請參見如何使用“會話追蹤方案”排查解析異常

  3. 設定HTTP要求標頭HOST欄位

    標準的HTTP協議中服務端會將HTTP要求標頭HOST欄位的值作為請求的網域名稱資訊進行解析。

    使用HTTPDNS後,您可能需要將HTTP請求URL中的HOST欄位替換為HTTPDNS解析獲得的IP,這時標準的網路程式庫會將您的IP賦值給HTTP要求標頭的HOST欄位,進而導致服務端的解析異常(服務端認可的是您的網域名稱資訊,而非IP資訊)。

    為瞭解決這個問題,您可以主動設定HTTP請求HOST欄位的值,如:

    String originalUrl = "http://www.aliyun.com/";
    URL url = new URL(originalURL);
    String originalHost = url.getHost();
    // 非同步介面擷取IP
    String ip = httpdns.getIpByHostAsync(originalHost);
    HttpURLConnection conn;
    if (ip != null) {
        // 通過HTTPDNS擷取IP成功,進行URL替換和HOST頭設定
        url = new URL(originalUrl.replaceFirst(originalHost, ip));
        conn = (HttpURLConnection) url.openConnection();
        // 佈建要求HOST欄位
        conn.setRequestProperty("Host", originalHost);
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }
  4. Cookie欄位

    部分網路程式庫支援Cookie的自動儲存管理,當您使用HTTPDNS進行IP URL請求時,部分網路程式庫會將您URL中的IP資訊作為Cookie對應的網域名稱資訊進行儲存管理(而非HTTP要求標頭HOST欄位資訊),進而造成Cookie管理與使用上的困擾,因此您需要關閉Cookie的自動管理功能(預設關閉)。

  5. HTTPS/WebView/SNI情境

    1. HTTPS情境,參考Android端HTTPS(含SNI)業務情境:IP直連方案

    2. WebView情境,參考Android端HTTPDNS+Webview最佳實務

  6. 代理情況下的使用

    當存在中間HTTP代理時,用戶端發起的請求中請求行會使用絕對路徑的URL,在您開啟HTTPDNS並採用IP URL進行訪問時,中間代理將識別您的IP資訊並將其作為真實訪問的HOST資訊傳遞給目標伺服器,這時目標伺服器將無法處理這類無真實HOST資訊的HTTP請求。

    移動網關提供了X-Online-Host的私人協議欄位來解決這個問題,比如:

    目標URL:http://www.example.com/product/oss/
    通過HTTPDNS解析出來的www.example.com的IP:192.168.XX.XX
    代理:10.0.XX.XX:XX
    您的HTTP要求標頭:
    GET http://192.168.XX.XX/product/oss/ HTTP/1.1     # 通過代理髮起的HTTP要求標頭,請求行是一個絕對路徑
    Host: www.example.com                         # 這個Header會被代理網關忽略,代理網關會使用請求行絕對路徑中的host欄位作為來源站點的host,即192.168.XX.XX
    X-Online-Host: www.example.com                # 這個Header就是移動網關為了傳遞真實Host添加的私人頭部,來源站點需要配置識別該私人頭部以擷取真實的Host資訊

    同樣您可以通過setRequestProperty方法進行X-Online-Host要求標頭域的設定,並在服務端設定對該私人頭域的解析。

    說明

    在絕大多數情境下,我們建議您在代理模式下關閉HTTPDNS功能。