HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android)

jopen 9年前發布 | 59K 次閱讀 網絡工具包 HTTPDNSLib

該項目是手機微博研發團隊和手機微博技術保障部共同努力的成果。

在此特別感謝:

張杰 微博:@木澤水

王春生 微博:@平凡的香草

胡波 微博:@胡波_

韓超 微博:@超朝炒觘

趙星宇 微博:@淘淘不逃008

聶鈺 微博:@古夜

馮磊 微博:@馮磊424

等同學的支持。 感謝大家提出的寶貴意見,感謝大家為該項目付出的努力!

項目中有任何問題歡迎大家來吐槽,一起完善、一起提高、一起使用!

email: xingyu10@staff.weibo.com fenglei1@staff.sina.com.cn

接入說明:

由于該工程需要用戶自定義部分配置文件,所以建議以源碼方式使用。(同時也支持項目中設定lib庫的參數) lib庫目前還沒有打包成 jar 文件, 大家測試使用的話可以直接將工程包含到自己的工程內即可。 apk文件夾下內有打包好的對httpDNS庫進行測試的程序。 該測試程序模擬了用戶使用的場景,并且記錄了相關統計數據。以及Lib庫的時時的狀態信息。

在AndroidManifest.xml文件中需要配置

  <!-- 主要注冊一個廣播 監聽網絡發生變化,本地更新dns解析記錄-->
    <receiver
        android:name="com.sina.util.networktype.NetworkStateReceiver"
        android:label="NetworkConnection" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.intent.action.USER_PRESENT" />
        </intent-filter>
    </receiver>
<!-- 需要配置的權限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

在使用 http dns前 需要初始化一次

DNSCache.Init(this);

直接調用該方法獲取 A記錄對象

DomainInfo[] infoList = DNSCache.getInstance().getDomainServerIp( " http://api.weibo.cn/index.html " ) ;

//DomainInfo 返回有可能為null,如果為空則使用域名直接請求數據吧~ 因為在http server 故障的時候會出現這個問題。

if( infoList != null ) { 
//A記錄可能會返回多個, 沒有特殊需求直接使用第一個即可。  這個數組是經過排序的。 
DomainInfo domainModel = infoList[0] ;  

//這里是 android 請求網絡。  只需要在http頭里添加一個數據即可。 省下的請求數據和原先一樣。
HttpGet getMethod = new HttpGet( domainModel.url );  
getMethod.setHeader("host", domainModel.host);
HttpClient httpClient = new DefaultHttpClient();  
long startDomainRequests = System.currentTimeMillis(); 
HttpResponse response = httpClient.execute(getMethod); 
String res = EntityUtils.toString(response.getEntity(), "utf-8") ; 
Log.d("DINFO", res) ; 

//在請求倒數據后,請配合將一部分信息傳遞給我。 lib庫里面會對這個服務器進行評分計算,lib庫永遠會優先給你最快,最穩定的服務器地址。
domainModel.code = String.valueOf( response.getStatusLine().getStatusCode() );
domainModel.data = res ;
domainModel.startTime = String.valueOf(startDomainRequests) ;
DNSCache.getInstance().setDomainServerIpInfo( domainModel );
}

更多配置

你可以創建一個 com.sina.util.dnscache.DNSCacheConfig.Data 對象分別設置下面屬性。然后調用 DNSCacheConfig.saveLocalConfigAndSync 方法傳入 設定好的 配置選項。

    /**
     * 是否啟用自己家的HTTP_DNS服務器 默認不啟用 | 1啟用 0不啟用
     */
    public String IS_MY_HTTP_SERVER = null;
    /**
     * 自己家HTTP_DNS服務API地址 使用時直接在字符串后面拼接domain地址 |
     * 示例(http://xxx.xxx.xxx.xxx/dns?domain=)+ domain
     */
    public String HTTPDNS_SERVER_API = null;
    /**
     * 是否啟用dnspod服務器 默認不啟用 | 1啟用 0不啟用
     */
    public String IS_DNSPOD_SERVER = null;
    /**
     * DNSPOD HTTP_DNS 服務器API地址 | 默認(http://119.29.29.29/d?ttl=1&dn=)
     */
    public String DNSPOD_SERVER_API = null;
    /**
     * DNSPOD 企業級ID配置選項 
     */
    public String DNSPOD_ID = null;
    /**
     * DNSPOD 企業級KEY配置選項 
     */
    public String DNSPOD_KEY = null;
    /**
     * 是否開啟 本地排序插件算法 默認開啟 | 1開啟 0不開啟
     */
    public String IS_SORT = null;
    /**
     * 速度插件 比重分配值:默認40%
     */
    public String SPEEDTEST_PLUGIN_NUM = null;
    /**
     * 服務器推薦優先級插件 比重分配:默認30% (需要自家HTTP_DNS服務器支持)
     */
    public String PRIORITY_PLUGIN_NUM = null;
    /**
     * 歷史成功次數計算插件 比重分配:默認10%
     */
    public String SUCCESSNUM_PLUGIN_NUM = null;
    /**
     * 歷史錯誤次數計算插件 比重分配:默認10%
     */
    public String ERRNUM_PLUGIN_NUM = null;
    /**
     * 最后一次成功時間計算插件 比重分配:默認10%
     */
    public String SUCCESSTIME_PLUGIN_NUM = null;
    /**
     * domain對應的測速文件,如果需要對服務器進行測速請給domain設置一個可以下載的資源文件來計算服務器速度
     */
    public ArrayList<String> SPEEDPATH_LIST = new ArrayList<String>();

動態更新參數

DNSCacheConfig 類下的 ConfigText_API 字段可以配置成自動更新配置參數的接口。 該接口返回json數據類型 具體數據格式詳見DNSCacheConfig.Data toJson()方法。

自己家HttpDNS服務接入

首先開啟 DNSCacheConfig.Data.IS_MY_HTTP_SERVER = 1 ; 然后設定 DNSCacheConfig.Data.HTTPDNS_SERVER_API 接口地址 示例( http://XXX.XXX.XXX.XXX/dns?domain=)+ domain

該接口返回格式(當然你也可以自定義格式需要重載 com.sina.util.dnscache.httpdns.IJsonParser 類即可): { "domain": "api.weibo.cn", "device_ip": "10.209.70.192", "device_sp": "0", "dns": [ { "priority": "0", "ip": "123.125.105.231", "ttl": "60" }, { "priority": "0", "ip": "123.125.105.246", "ttl": "60" }, { "priority": "0", "ip": "202.108.7.133", "ttl": "60" } ] } PS: priority 字段是服務器推薦優先級。 | device_sp 字段是該設備出口運營商。

HttpDns是什么?

如果你對 httpdns 還不了解他是什么!

你可以閱讀: 【鵝廠網事】全局精確流量調度新思路-HttpDNS服務詳解

傳統DNS解析 和 HTTPDNS解析 本質的區別:

傳統DNS解析

客戶端發送udp數據包到dns服務器,dns服務器返回該域名的相關A記錄信息。

HTTPDNS解析

客戶端發起http請求攜帶需要查詢的域名,通過IP直接訪問服務器,該Http服務器接倒請求后返回域名對應的A記錄。

HttpDns sdk (android版本)

希望解決的問題:

1.LocalDNS劫持
2.平均訪問延遲下降
3.用戶連接失敗率下降

目錄結構說明:

HttpDns/code/DNSCache --- HttpDns lib庫主工程。
HttpDns/code/DNSCacheTest --- HttpDns庫測試工程。
HttpDns/doc --- 項目相關的一些文檔、流程圖、結構圖等。
HttpDns/ui/DNSCacheTest --- 存放HttpDns測試項目UI源文件以及切圖文件。

HttpDns 交互流程

HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android)

HttpDns Lib庫交互流程

HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android)

查詢模塊

檢測本地是否有相應的域名緩存
沒有記錄則根據當前運營商返回內置的ip節點
從httpdns查詢域名相應A記錄,緩存域名信息
查詢模塊必須保證響應速度,基于已有設備測試平均在5毫秒左右

數據緩存模塊

根據sp(或wifi名)緩存域名信息
根據sp(或wifi名)緩存服務器ip信息、優先級
記錄服務器ip每次請求成功數、錯誤數
記錄服務器ip最后成功訪問時間、最后測速
添加 內存 -》數據庫 之間的緩存層

評估模塊

根據本地數據,對一組ip排序
處理用戶反饋回來的請求明細,入庫
針對用戶反饋是失敗請求,進行分析上報預警
給HttpDns服務端智能分配A記錄提供數據依據

評估算法插件

本次測速 - 對ip組的每個ip測速打分
官方推薦 - HttpDns接口 A記錄中返回的優先級
歷史成功 - 該ip7天內成功訪問次數
歷史錯誤 - 該ip7天內訪問錯誤次數
最后成功時間 - 該ip最后一次成功時間,閾值24

打分比重權值分配

對每個IP打分,總分100分。
本次測速 - 40分
官方推薦 - 30分
歷史成功 - 10分
歷史錯誤 - 10分
最后成功時間 - 10分
總分=本次測速+官方推薦+歷史成功次數+歷史錯誤次數+最后成功時間

目前權重分配完全基于主觀認識,后期會根據建立的相應基線進行權重分配調整。

使用者需要自己權衡,有可能隨機的ip速度都好于權重打分的ip。

PS:給出一副算法計算分數時的細節圖,有興趣的朋友可以一起探討研究。

HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android)

你可能更需要“它” HttpHook(android版本)(工程還未上傳)

HttpHook是一個轉發http請求工具庫。

他可以讓你在不修改工程源代碼的情況下對網絡層進行修改、替換、等更多的操作。

由于我沒有微博客戶端的源碼,為了測試微博客戶端是否可以正常使用httpdns庫,才誕生的這個項目。

HttpHook 截取 api.weibo.cn 的所有請求,提取到url。

將url中的host域名,傳入httpdns庫中,使用返回的a記錄替換host,進行訪問。

訪問服務器成功后,在將服務器返回的數據傳給 客戶端,從而完成一次訪問請求。

這是在 httpdns 項目中使用場景。 大家如果感興趣可以到httphook項目中詳細查看。

HttpDns Test (android版本)

測試工程主要最初為了模擬用戶使用APP發出的網絡請求,進行數據記錄和對比。

在頁面中能很直觀的看到每個任務的相關信息。

比如:任務總耗時,httpdns lib庫耗時、http請求耗時、以及設備當前環境信息 等。。

由于UE,UI都是自己設計,對于表達信息的布局和美觀可能還有欠缺,本程序猿的能力有限,大家多多包涵。

你未必會需要“它”,上傳幾張測試工程的截圖,提供參考。

HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android) HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android) HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android) HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android) HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android) HTTPDNSLib - 一個支持 DNSPod D+ 和自定義 HttpDNS 服務的 HttpDNS SDK(Android)

項目主頁:http://www.baiduhome.net/lib/view/home/1437364446240


 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!