Dns&HttpDns

目錄

1、Dns
2、HttpDns

1、Dns

dns流程
  1. 終端向LocalDNS發(fā)起遞歸查詢。

  2. LocalDNS(未開啟轉(zhuǎn)發(fā)模式),則向根DNS服務(wù)器發(fā)起迭代查詢請(qǐng)求。(如開啟轉(zhuǎn)發(fā)模式,則轉(zhuǎn)發(fā)至上級(jí)localDns)

(任何LocalDNS都需知道根DNS服務(wù)器的IP地址(全球共13臺(tái))。)

  1. 根DNS服務(wù)器返回一級(jí)域名服務(wù)器IP地址,(com DNS服務(wù)器的IP地址)。

(LocalDNS將com DNS服務(wù)器及其IP地址加入到緩存,下次DNS請(qǐng)求,在緩存未過(guò)期的情況下,授權(quán)給com 區(qū)的域名需向com DNS服務(wù)器請(qǐng)求查詢時(shí),直接往com DNS服務(wù)器發(fā)查詢請(qǐng)求,不再向根DNS服務(wù)器請(qǐng)求。)

  1. LocalDNS服務(wù)器向一級(jí)域名服務(wù)器(com DNS服務(wù)器)發(fā)起迭代查詢請(qǐng)求。

  2. com DNS服務(wù)器返回二級(jí)域名服務(wù)器IP地址(wangsu.com DNS服務(wù)器的IP地址)。

(LocalDNS將wangsu.comDNS服務(wù)器及其IP地址加入到緩存,下次DNS請(qǐng)求,在緩存未過(guò)期的情況下,授權(quán)給wangsu.com區(qū)的域名需向wangsu.com DNS服務(wù)器請(qǐng)求查詢時(shí),直接往對(duì)應(yīng) DNS服務(wù)器發(fā)查詢請(qǐng)求,不再向根DNS服務(wù)器及com DNS服務(wù)器請(qǐng)求。)

  1. LocalDNS服務(wù)器向wangsu.com DNS服務(wù)器發(fā)起迭代查詢請(qǐng)求。

7.wangsu.com DNS服務(wù)器給出域名的IP地址。

(LocalDNS將www.wangsu.com
IP地址加入到緩存,下次相同的DNS請(qǐng)求,在緩存未過(guò)期的情況下,LocalDNS直接給出該域名的IP地址,不再向權(quán)威DNS服務(wù)器查詢。)

  1. LocalDNS服務(wù)器將該域名對(duì)應(yīng)的IP地址返回給終端用戶,

(DNS客戶端將域名對(duì)應(yīng)的IP地址接入緩存。下次請(qǐng)求該域名時(shí),若緩存未過(guò)期,DNS客戶端直接從緩存取出IP,不再向LocalDNS發(fā)起迭代查詢。)

遞歸查詢指如果終端用戶所請(qǐng)求的LocalDNS服務(wù)器不知道被查詢的域名的IP地址,則以DNS客戶端的身份,向其它域名服務(wù)器繼續(xù)發(fā)出查詢請(qǐng)求報(bào)文(即替主機(jī)繼續(xù)查詢),而不是讓主機(jī)自己進(jìn)行下一步查詢。因此,遞歸查詢返回的查詢結(jié)果或者是所要查詢的IP地址,或者是報(bào)錯(cuò),表示無(wú)法查詢到所需的IP地址。

迭代查詢指域名服務(wù)器或者給出最終結(jié)果,或者告訴DNS客戶(此處指LocalDNS)應(yīng)去哪些DNS服務(wù)器查詢。

遞歸查詢LocalDNS如果沒有記錄客戶端發(fā)過(guò)來(lái)的域名對(duì)應(yīng)的ip地址,則以客戶端的身份,根域名服務(wù)器發(fā)起迭代查詢,迭代查詢是值,根域名服務(wù)器不直接告訴LocalDNS結(jié)果,而是告訴LocalDNS去哪里查詢,然后LocalDNS一級(jí)一級(jí)的查詢,直至最終得到結(jié)果。

2、httpdns

2.1、httpdns解決的問題

2.1.1、域名劫持

1、黑客侵入了寬帶路由器并對(duì)Local DNS進(jìn)行篡改;
2、攻擊者還可以監(jiān)聽終端用戶的域名解析請(qǐng)求,并在Local DNS返回正確結(jié)果之前將偽造的DNS解析響應(yīng)傳遞給終端用戶
3、Local DNS針對(duì)部分域名的緩存進(jìn)行更改

2.1.2、調(diào)度不精準(zhǔn)

由于運(yùn)營(yíng)商策略的多樣性,其 Local DNS 的解析結(jié)果可能不是最近、最優(yōu)的節(jié)點(diǎn)。

部分Local DNS A供應(yīng)商為了降低運(yùn)營(yíng)成本,會(huì)將請(qǐng)求到自己節(jié)點(diǎn)的域名解析請(qǐng)求轉(zhuǎn)發(fā)給其他供應(yīng)商的Local DNS B節(jié)點(diǎn),Local DNS B請(qǐng)求權(quán)威dns解析時(shí),權(quán)威dns會(huì)根據(jù)Local DNS B的ip,分配離Local DNS B地理位置最近的ip地址。

Local DNS的布點(diǎn)受成本因素制約分布并不均勻也會(huì)導(dǎo)致上述調(diào)度不準(zhǔn)的問題。

2.2、HTTPDNS

1、使用HTTP協(xié)議進(jìn)行域名解析,將域名解析請(qǐng)求直接發(fā)送到HTTPDNS服務(wù)端,繞過(guò)運(yùn)營(yíng)商 Local DNS ,避免域名劫持。
2、HTTPDNS服務(wù)端會(huì)將終端用戶的IP信息直接交付給權(quán)威DNS,從而解決調(diào)度不精準(zhǔn)的問題。
3、另外通過(guò)域名預(yù)解析、緩存(DNS解析結(jié)果)、(解析結(jié)果)懶更新策略等方式實(shí)現(xiàn)無(wú)延遲解析。

2.2.1、預(yù)加載

app啟動(dòng)時(shí),可以對(duì)我們后續(xù)需要用到的域名,調(diào)用HTTPDNS SDK中的預(yù)解析方法發(fā)起異步的預(yù)解析請(qǐng)求。

域名預(yù)解析
2.2.2、懶更新

所謂懶加載策略,核心的實(shí)現(xiàn)思路如下:

1、如果緩存中沒有記錄,那么異步網(wǎng)絡(luò)請(qǐng)求HTTPDNS解析,獲取解析結(jié)果。
(網(wǎng)絡(luò)請(qǐng)求需要異步,同步調(diào)用需要直接拿到結(jié)果,可采取線程池+Future的策略)
2、如果緩存中存在記錄,不論過(guò)期與否,直接返回業(yè)務(wù)層緩存中的記錄;
3、如果緩存中的記錄已過(guò)期,后臺(tái)發(fā)起異步網(wǎng)絡(luò)請(qǐng)求進(jìn)行HTTPDNS解析;

絕大多數(shù)場(chǎng)景下域名對(duì)應(yīng)IP變更并不頻繁,特別是在單次APP的使用周期內(nèi),域名解析出的IP往往是相同的。
另一方面,即使域名對(duì)應(yīng)的IP發(fā)生改變,后臺(tái)會(huì)異步發(fā)起的異步HTTPDNS解析解析會(huì)很快獲取最新解析結(jié)果 ,結(jié)合我們的網(wǎng)絡(luò)重試策略,保證了下一次網(wǎng)絡(luò)請(qǐng)求的正確性。

懶更新
2.2.3、OKhttp+HttpDns
public class OkHttpDns implements Dns {
    private static final Dns SYSTEM = Dns.SYSTEM;
    HttpDnsService httpdns;//httpdns 解析服務(wù)
    private static OkHttpDns instance = null;
    private OkHttpDns(Context context) {
        this.httpdns = HttpDns.getService(context, "account id");
    }
    public static OkHttpDns getInstance(Context context) {
        if(instance == null) {
            instance = new OkHttpDns(context);
        }
        return instance;
    }
    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        //通過(guò)異步解析接口獲取ip
        String ip = httpdnsManager.getIpByHost(hostname);
        if(ip != null) {
            //如果ip不為null,直接使用該ip進(jìn)行網(wǎng)絡(luò)請(qǐng)求
            List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
            Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
            return inetAddresses;
        }
        //如果返回null,走系統(tǒng)DNS服務(wù)解析域名
        return Dns.SYSTEM.lookup(hostname);
    }
}

//給okhttpclient設(shè)置自定義的dns
private void okhttpDnsRequest() {
    OkHttpClient client = new OkHttpClient.Builder()
    .dns(OkHttpDns.getInstance(getApplicationContext()))
    .build();

自定義一個(gè)類實(shí)現(xiàn)Dns,并重寫Dns的lookup方法,
在這個(gè)方法中結(jié)合懶更新策略獲取域名對(duì)應(yīng)的ip,包裝成InetAddress list進(jìn)行返回。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容