本章節介紹了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檔案,在allprojects
的repositories
中添加Maven倉庫地址:
allprojects {
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
}
}
7.0以上版本
開啟專案根目錄的settings.gradle檔案,在dependencyResolutionManagement
的repositores
中添加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執行個體的方式提供網域名稱解析服務,您可以通過以下方式擷取執行個體。
普通方式
HttpDnsService httpdns = HttpDns.getService(applicationContext, accountID); // 參數applicationContext是您Android App的Context // 參數accountID是系統分配的Account ID,當您開通HTTPDNS後,您可以在控制台擷取到您對應的Account ID資訊
鑒權方式
說明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請求。
注意事項
務必編寫降級代碼
降級代碼指的是HTTPDNS無法擷取期望結果時的處理代碼。請參見設定降級策略相關介面。
記錄從HTTPDNS擷取的IP及sessionId
我們提供了用於解析問題排查的解決方案,需要您將從HTTPDNS擷取的IP及sessionId記錄到日誌中,詳情請參見如何使用“會話追蹤方案”排查解析異常。
設定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(); }
Cookie欄位
部分網路程式庫支援Cookie的自動儲存管理,當您使用HTTPDNS進行IP URL請求時,部分網路程式庫會將您URL中的IP資訊作為Cookie對應的網域名稱資訊進行儲存管理(而非HTTP要求標頭HOST欄位資訊),進而造成Cookie管理與使用上的困擾,因此您需要關閉Cookie的自動管理功能(預設關閉)。
HTTPS/WebView/SNI情境
HTTPS情境,參考Android端HTTPS(含SNI)業務情境:IP直連方案。
WebView情境,參考Android端HTTPDNS+Webview最佳實務。
代理情況下的使用
當存在中間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功能。