網絡協議 17 - HTTPDNS:私人定製的 DNS 服務

【前五篇】系列文章傳送門:html

  1. 網絡協議 12 - HTTP 協議:經常使用而不簡單
  2. 網絡協議 13 - HTTPS 協議:加密路上無盡頭
  3. 網絡協議 14 - 流媒體協議:要說愛你不容易
  4. 網絡協議 15 - P2P 協議:小種子大學問
  5. 網絡協議 16 - DNS 協議:網絡世界的地址簿

    全球統一的 DNS 是很權威,可是咱們都知道「適合本身的,纔是最好的」。不少時候,標準統一化的 DNS 並不能知足咱們定製的需求,這個時候就須要 HTTPDNS 了。sql

    上一節咱們知道了 DNS 能夠根據名稱查地址,也能夠針對多個地址作負載均衡。然而,咱們信任的地址簿也會存在指錯路的狀況。明明離你 500 米就有個吃飯的地方,非要把你推薦到 5 千米外。爲何會出現這樣的狀況呢?數據庫

    還記得嗎?由咱們發出請求解析 DNS 的時候,首先會鏈接到運營商本地的 DNS 服務器,由這個服務器幫咱們去整棵 「DNS 樹」 上進行解析,而後將解析的結果返回給客戶端。可是本地的 DNS 服務器,做爲一個本地導遊,每每會有本身的「當心思」。設計模式

傳統 DNS 存在的問題

1)域名緩存問題
    它能夠在本地作一個緩存。也就是說,不是每個請求,它都會去訪問權威 DNS 服務器,而是把訪問過一次的結果緩存到本地,當其餘人來問的時候,直接返回緩存的內容。緩存

    這就至關於導遊去過一個飯店,本身記住了地址,當有一個遊客問的時候,他就憑記憶回答了,不用再去查地址簿。這樣會存在一個問題,遊客問的那個飯店若是已經搬走了,然而由於導遊沒有刷新「記憶緩存」,致使遊客白跑一趟。安全

    另外,有的運營商會把一些靜態頁面,緩存到本運營商的服務器內,這樣用戶請求的時候,就不用跨運營商進行訪問,既加快了速度,也減小了運營商直接流量計算的成本。也就是說,在域名解析的時候,不會將用戶導向真正的網站,而是指向這個緩存的服務器。服務器

    緩存的問題,不少狀況下是看不出問題的,可是當頁面更新,用戶訪問到老的頁面,問題就出來了。網絡

    再就是本地的緩存,每每使得全局負載均衡失敗。上次進行緩存的時候,緩存中的地址不必定是客戶這次訪問離客戶最近的地方,若是把這個地址返回給客戶,就會讓客戶繞遠路了。
2)域名轉發問題
    還記得咱們域名解析的過程嗎?捂臉是本地域名解析,仍是去權威 DNS 服務器中查找,均可以認爲是一種外包形式。有了請求,直接轉發給其餘服務去解析。若是轉發的是權威 DNS 服務器還好說,可是若是由於「偷懶」轉發給了鄰居服務器去解析,就容易產生跨運營商訪問的問題。架構

    這就好像,若是 A 運營商的客戶,訪問本身運營商的 DNS 服務器,A 運營商去權威 DNS 服務器查詢的話,會查到客戶的 A 運營商的,返回一個部署在 A 運營商的網站地址,這樣針對相同運營商的訪問,速度就會快不少。併發

    可是若是 A 運營商偷懶,沒有轉發給權威 DNS ,而是轉發給了 B 運營商,讓 B 運營商再去權威 DNS 服務器查詢,這樣就會讓權威服務器誤認爲客戶是 B 運營商的,返回一個 B 運營商的服務器地址,致使客戶每次都要跨運營商訪問,訪問速度就會慢下來。

3)出口 NAT 問題
    前面瞭解網關的時候,咱們知道,出口的時候,不少機房都會配置 NAT,也就是網絡地址轉換,使得從這個網關出去的包,都換成新的 IP 地址。

    這種狀況下,權威 DNS 服務器就沒辦法經過請求 IP 來判斷客戶究竟是哪一個運營商的,頗有可能誤判運營商,致使跨運營商訪問。

4)域名更新問題
    本地 DNS 服務器是由不一樣地區、不一樣運營商獨立部署的。對域名解析緩存的處理上,實現策略也有區別。有的會偷懶,忽略域名解析結構的 TTL 時間限制,在權威 DNS 服務器解析變動的時候,解析結果在全網生效的週期很是漫長。可是有的場景,在 DNS 的切換中,對生效時間要求比較高。

    例如雙機房部署的是,跨機房的負載均衡和容災多使用 DNS 來作。當一個機房出問題以後,須要修改權威 DNS,將域名指向新的 IP 地址。可是若是更新太慢,不少用戶都會訪問一次。

5)解析延遲問題
    從 DNS 的查詢過程來看,DNS 的查詢過程須要遞歸遍歷多個 DNS 服務器,才能得到最終的解析結果,這帶來必定的延時,甚至會解析超時。

    上面總結了 DNS 的五個問題。問題有了,總得有解決辦法,就像由於 HTTP 的安全問題,才火了 HTTPS 協議同樣,對應的,也有 HTTPDNS 來解決上述 DNS 出現的問題。

HTTPDNS

什麼是 HTTPDNS ?其實很簡單:

HTTPDNS 是基於 HTTP 協議和域名解析的流量調度解決方案。它不走傳統的 DNS 解析,而是本身搭建基於 HTTP 協議的 DNS 服務器集羣,分佈在多個地點和多個運營商。當客戶端須要 DNS 解析的時候,直接經過 HTTP 請求這個服務器集羣,獲得就近的地址。

    這就至關於每家基於 HTTP 協議,本身實現本身的域名解析,作一個本身的地址簿,而不使用統一的地址簿。可是咱們知道,域名解析默認都是走 DNS 的,於是使用 HTTPDNS 須要繞過默認的 DNS 路徑,也就不能使用默認的客戶端。**使用 HTTPDNS 的,每每是手機應用,須要在手機端嵌入支持 HTTPDNS 的客戶端 SDK。

HTTPDNS 的工做流程

    接下來,咱們一塊兒來認識下 HTTPDNS 的工做流程。

    HTTPDNS 會在客戶端的 SDK 裏動態請求服務端,獲取 HTTPDNS 服務器的 IP 列表,緩存在本地。隨着不斷地解析域名,SDK 也會在本地緩存 DNS 域名解析的結果。

    當手機應用要訪問一個地址的時候,首先看是否有本地的緩存,若是有直接返回。這個緩存和本地 DNS 的緩存不同的是,這個是手機應用本身作的,而非整個運營商統一作。如何更新以及什麼時候更新緩存,手機應用的客戶端能夠和服務器協調來作這件事情。

    若是本地沒有,就須要請求 HTTPDNS 的服務器,在本地 HTTPDNS 服務器的 IP 列表中,選擇一個發出 HTTP 請求,獲取一個要訪問的網站的 IP 列表。

請求的方式是這樣的:

curl http://123.4.5.6/d?dn=c.m.cnb...

    手機客戶端之道手機在哪一個運營商、哪一個地址。因爲是直接的 HTTP 通訊,HTTPDNS 服務器可以準確知道這些信息,於是能夠作精準的全局負載均衡。

    上面五個問題,歸結起來就兩大問題。一是解析速度和更新速度的平衡問題,二是智能調度的問題。HTTPDNS 對應的解決方案是 HTTPDNS 的緩存設計和調度設計。

HTTPDNS 的緩存設計

    解析 DNS 過程複雜,通訊此時多,對解析速度形成很大影響。爲了加快解析,於是有了緩存,可是這又會產生緩存更新速度不及時的問題。最要命的是,這兩個方面都掌握在別人手中,也就是本地 DNS 服務器手中,它不會爲你定製,做爲客戶端乾着急也沒辦法。

    而 HTTPDNS 就是將解析速度和更新速度所有掌控在本身手中。

    一方面,解析的過程,不須要本地 DNS 服務遞歸的調用一大圈,一個 HTTP 的請求直接搞定。要實時更新的時候,立刻就能起做用。

另外一方面,爲了提升解析速度,本地也有緩存,緩存是在客戶端 SDK 維護的,過時時間、更新時間,均可以本身控制。

HTTPDNS 的緩存設計策略也是我們作應用架構中經常使用的緩存設計模式,也即分爲客戶端、緩存、數據源三層。

  • 對於應用架構來說,就是應用、緩存、數據庫。常見的是 Tomcat、Redis、Mysql;
  • 對於 HTTPDNS 來說,就是手機客戶端、DNS 緩存、HTTPDNS 服務器。

clipboard.png

只要是緩存模式,就存在緩存的過時、更新、不一致的問題,解決思路也是類似的。

例如,DNS 緩存在內存中,也能夠持久化到存儲上,從而 APP 重啓以後,可以儘快從存儲中加載上次累積的常常訪問的網站的解析結果,就不須要每次都所有解析一遍,再變成緩存。這有點像 Redis 是基於內存的緩存,可是一樣提供持久化的能力,使得重啓或者主備切換的時候,數據不會徹底丟失。

SDK 中的緩存會嚴格按照緩存過時時間,若是緩存沒有命中,或者已通過期,並且客戶端不容許使用過時的概率,則會發起一次解析,保證緩存記錄是更新的。

解析能夠同步進行,也就是直接調用 HTTPDNS 的接口,返回最新的記錄,更新緩存。也能夠異步進行,添加一個解析任務到後臺,由後臺任務調用 HTTPDNS 的接口。

同步更新的優勢是實時性好,缺點是若是有多個請求都發現過時的時候,會同時請求 HTTPDNS 屢次,形成資源浪費。

同步更新的方式對應到應用架構緩存的 Cache-Aside 機制,也就是先讀緩存,不命中讀數據庫,同時將結果寫入緩存。

clipboard.png

異步更新的優勢是,能夠將多個請求都發現過時的狀況,合併爲一個對於 HTTPDNS 的請求任務,只執行一次,減小 HTTPDNS 的壓力。同時,能夠在即將過時的時候,就建立一個任務進行預加載,防止過時以後再刷新,稱爲預加載

它的缺點是,當前請求拿到過時數據的時候,若是客戶端容許使用過時時間,須要冒一次風險。此次風險是指,若是過時的請求還能請求,就沒問題,若是不能請求,就會失敗一次,等下次緩存更新後,才能請求成功。

clipboard.png

異步更新的機制,對應到應用架構緩存的 Refresh-Ahead 機制,即業務僅僅訪問緩存,當過時的時候按期刷新。在著名的應用緩存 Guava Cache 中,有個 RefreshAfterWrite 機制,對於併發狀況下,多個緩存訪問不命中從而引起併發回源的請求,能夠採起只有一個請求回源的模式。在應用架構的緩存中,也經常用數據預熱或者預加載的機制。

HTTPDNS 的調度設計

因爲客戶端嵌入了 SDK,於是就不會由於本地 DNS 的各類緩存、轉發、NAT,讓權威 DNS 服務器誤會客戶端所在的位置和運營商,從而能夠拿到第一手資料。

在客戶端,能夠知道手機是哪一個國家、哪一個運營商、哪一個省、甚至是哪一個市,HTTPDNS 服務端能夠根據這些信息,選擇最佳的服務節點返回。

若是有多個節點,還會考慮錯誤率、請求時間、服務器壓力、網絡狀態等,進行綜合選擇,而非僅僅考慮地理位置。當有一個節點宕機或者性能降低的時候,能夠儘快進行切換。

要作到這一點,須要客戶端使用 HTTPDNS 返回的 IP 訪問業務應用。客戶端的 SDK 會收集網絡請求數據,如錯誤率、請求時間等網絡請求質量數據,併發送到統計後臺,進行分析、聚合,以此查看不一樣 IP 的服務質量。

在服務端,應用能夠經過調用 HTTPDNS 的管理接口,配置不一樣服務質量的優先級、權重。HTTPDNS 會根據這些策略綜合地理位置和線路情況算出一個排序,優先訪問當前那些優質的、時延低的 IP 地址。

HTTPDNS 經過智能調度以後返回的結果,也會緩存在客戶端。爲了避免讓緩存使得調度失真,客戶端能夠根據不一樣的移動網絡運營商的 SSID 來分維度緩存。不一樣的運營商解析出來的結果會不一樣。

小結

  • 傳統 DNS 會由於緩存、轉發、NAT 等問題致使客戶端誤會本身所在的位置和運營商,從而影響流量的調度;
  • HTTPDNS 經過客戶端 SDK 和服務端,經過 HTTP 直接調用解析 DNS 的方式,繞過了傳統 DNS 的缺點,實現了智能的調度。

參考:

  1. HTTPDNS 的原理
  2. 劉超 - 趣談網絡協議系列課;
相關文章
相關標籤/搜索