對於互聯網,域名是訪問的第一跳,而這一跳不少時候會「失足」(尤爲是移動端網絡),致使訪問錯誤內容、失敗鏈接等,讓用戶在互聯網上暢遊的爽快瞬間消失。php
而對於這關鍵的第一跳,包括鵝廠在內的國內互聯網大廠,都在持續深刻地研究和思考對策,本文將就鵝廠團隊在這一塊的技術實踐,作一個深度的總結和技術分享,但願給你們帶來些許啓發。html
學習交流:android
- 即時通信/推送技術開發交流4羣:101279154[推薦]git
- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》程序員
(本文同步發佈於:http://www.52im.net/thread-2121-1-1.html)github
《網絡編程懶人入門(一):快速理解網絡通訊協議(上篇)》算法
《網絡編程懶人入門(二):快速理解網絡通訊協議(下篇)》數據庫
《網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門》編程
《網絡編程懶人入門(七):深刻淺出,全面理解HTTP協議》json
《網絡編程懶人入門(九):通俗講解,有了IP地址,爲什麼還要用MAC地址?》
《技術掃盲:新一代基於UDP的低延時網絡傳輸層協議——QUIC詳解》
《現代移動端網絡短鏈接的優化手段總結:請求速度、弱網適應、安全保障》
《移動端IM開發者必讀(一):通俗易懂,理解移動網絡的「弱」和「慢」》
《移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結》
但凡使用域名來給用戶提供服務的互聯網企業,都或多或少地沒法避免在有中國特點的互聯網環境中遭遇到各類域名被緩存、用戶跨網訪問緩慢等問題。那麼對於騰訊這樣的域名數量在10萬級別的互聯網公司來說,域名解析異常的狀況到底有多嚴重呢?
天天騰訊的分佈式域名解析監測系統在不停地對全國全部的重點LocalDNS(指運營商的DNS服務)進行探測,騰訊域名在全國各地的日解析異常量是已經超過了80萬條(這方面,來自移動端的異常尤其突出)。這給騰訊的業務帶來了巨大的損失。爲此騰訊創建了專業的團隊與各個運營商進行了深度溝通,可是因爲各類緣由,處理效率及效果均不能達到騰訊各業務部門的需求。
除了和運營商進行溝通,有沒有一種技術上的方案,能從根源上解決域名解析異常及用戶訪問跨網的問題呢?這是包括騰訊在內的不少國內互聯網大廠技術團隊一直在思考的問題。
要想理解本文將要討論的DNS各類問題,咱們須要首先來複習一下DNS的基本原理和相關知識。
DNS(Domain Name System,域名系統),DNS 服務用於在網絡請求時,將域名轉爲 IP 地址。可以使用戶更方便的訪問互聯網,而不用去記住可以被機器直接讀取的 IP 數串。
DNS的基一原理以下圖所示:
傳統的基於 UDP 協議的公共 DNS 服務極易發生 DNS 劫持,從而形成安全問題。
如上圖所示,典型DNS域名系統的結構以下:
1)Root 域名:DNS 域名使用時,規定由尾部句號來指定名稱位於根或更高級別的域層次結構;
2)Top Level 頂級域名:用來指示某個國家、地區或組織使用的名稱的類型名稱。如 .net;
3)Second Level 域名:我的或組織在 Internet 上使用的註冊名稱。如 52im.net;
4)Third Level 域名:已註冊的二級域名派生的域名。如 docs.52im.net。
如上圖所示,這是一個典型的域名解析過程:
1)瀏覽器中輸入 www.52im.net,發出解析請求;
2)本機的域名解析器 resolver 程序查詢本地緩存和 host 文件中是否爲域名的映射關係,若是有則調用這個 IP 地址映射,完成解析;
3)若是 hosts 與本地解析器緩存都沒有相應的網址映射關係,則本地解析器會向 TCP/IP 參數中設置的首選 DNS 服務器(咱們叫它 Local DNS 服務器)發起一個遞歸的查詢請求;
4)服務器收到查詢時,若是要查詢的域名由本機負責解析,則返回解析結果給客戶機,完成域名解析,此解析具備權威性。若是要查詢的域名,不禁 Local DNS 服務器解析,但該服務器已緩存了此網址映射關係,則調用這個 IP 地址映射,完成域名解析,此解析不具備權威性;
5)若是 Local DNS 服務器本地區域文件與緩存解析都失效,則根據 Local DNS 服務器的設置(是否遞歸)進行查詢,若是未用開啓模式,Local DNS 就把請求發至13臺 Root DNS。若是用的是遞歸模式,此 DNS 服務器就會把請求轉發至上一級 DNS 服務器,由上一級服務器進行解析,上一級服務器若是不能解析,或找根 DNS 或把轉請求轉至上上級,以此循環;
6)Root DNS 服務器收到請求後會判斷這個域名是誰來受權管理,並會返回一個負責該頂級域名服務器的一個 IP;
7)Local DNS 服務器收到 IP 信息後,將會聯繫負責 .net 域的這臺服務器;
8)負責 .com 域的服務器收到請求後,若是本身沒法解析,它就會找一個管理 .net 域的下一級 DNS 服務器地址給本地 DNS 服務器;
9)當 Local DNS 服務器收到這個地址後,就會找 52im.net 域服務器,十、11重複上面的動做,進行查詢;
10)最後 www.52im.net 返回須要解析的域名的 IP 地址給 Local DNS 服務器;
11)Local DNS 服務器緩存這個解析結果(同時也會緩存,六、八、10返回的結果);
12)Local DNS 服務器同時將結果返回給本機域名解析器;
13)本機緩存解析結果;
14)本機解析器將結果返回給瀏覽器;
15)瀏覽器經過返回的 IP 地址發起請求。
遞歸查詢:若是主機所詢問的本地域名服務器不知道被查詢域名的 IP 地址,那麼本地域名服務器就以 DNS 客戶的身份,向其餘根域名服務器繼續發出查詢請求報文,而不是讓該主機本身進行下一步的查詢。
迭代查詢:當根域名服務器收到本地域名服務器發出的迭代查詢請求報文時,要麼給出所要查詢的 IP 地址,要麼告訴本地域名服務器:你下一步應當向哪個域名服務器進行查詢。而後讓本地域名服務器進行後續的查詢,而不是替本地域名服務器進行後續的查詢。
因而可知,客戶端到 Local DNS 服務器,Local DNS 與上級 DNS 服務器之間屬於遞歸查詢;DNS 服務器與根 DNS 服務器以前屬於迭代查詢。
實際環境中,由於採用遞歸模式會致使 DNS 服務器流量很大,因此如今大多數的 DNS 都是迭代模式。
總結下來,DNS的這些咋整主要的帶來了三類問題:
1)LocalDNS劫持;
2)平均訪問延遲降低;
3)用戶鏈接失敗率降低。
LocalDNS劫持: 因爲HttpDNS是經過ip直接請求http獲取服務器A記錄地址,不存在向本地運營商詢問domain解析過程,因此從根本避免了劫持問題。 (對於http內容tcp/ip層劫持,可使用驗證因子或者數據加密等方式來保證傳輸數據的可信度)
平均訪問延遲降低: 因爲是ip直接訪問省掉了一次domain解析過程,(即便系統有緩存速度也會稍快一些‘毫秒級’)經過智能算法排序後找到最快節點進行訪問。
用戶鏈接失敗率降低: 經過算法下降以往失敗率太高的服務器排序,經過時間近期訪問過的數據提升服務器排序,經過歷史訪問成功記錄提升服務器排序。若是ip(a)訪問錯誤,在下一次返回ip(b)或者ip(c) 排序後的記錄。
那麼,追根溯源,到底爲何會存在這些問題?這就是下一節要討論的問題。
咱們得先得了解下如今國內各ISP運營商的LocalDNS的基本狀況。
國內運營商LocalDNS形成的這些問題,能夠歸爲下如下3種緣由:
1)域名緩存;
2)解析轉發;
3)LocalDNS遞歸出口NAT。
下面,咱們來逐一分析。
域名緩存很好理解,就是LocalDNS緩存了騰訊的域名的解析結果,不向騰訊權威DNS發起遞歸。
示意圖以下:
爲什麼LocalDNS要把域名解析結果進行緩存呢?緣由有如下幾個:
1)保證用戶訪問流量在本網內消化:國內的各互聯網接入運營商的帶寬資源、網間結算費用、IDC機房分佈、網內ICP資源分佈等存在較大差別。爲了保證網內用戶的訪問質量,同時減小跨網結算,運營商在網內搭建了內容緩存服務器,經過把域名強行指向內容緩存服務器的IP地址,就實現了把本地本網流量徹底留在了本地的目的;
2)推送廣告:有部分LocalDNS會把部分域名解析結果的所指向的內容緩存,並替換成第三方廣告聯盟的廣告。
以上類型的行爲就是咱們常說的域名緩存,域名緩存會致使用戶產生如下的訪問異常:
A、僅對80端口的http服務作了緩存,若是域名是經過https協議或其它端口提供服務的,用戶訪問就會出現失敗。好比支付服務、遊戲經過指定端口鏈接connect server服務等;
B、緩存服務器的運維水平良莠不齊,時有出現緩存服務器故障致使用戶訪問異常的問題。
除了域名緩存之外,運營商的LocalDNS還存在解析轉發的現象。解析轉發是指運營商自身不進行域名遞歸解析,而是把域名解析請求轉發到其它運營商的遞歸DNS上的行爲。
正常的LocalDNS遞歸解析過程是這樣的:
而部分小運營商爲了節省資源,就直接將解析請求轉發到了其它運營的遞歸LocalDNS上去了:
這樣的直接後果就是騰訊權威DNS收到的域名解析請求的來源IP就成了其它運營商的IP,最終致使用戶流量被導向了錯誤的IDC,用戶訪問變慢。
LocalDNS遞歸出口NAT指的是運營商的LocalDNS按照標準的DNS協議進行遞歸,可是由於在網絡上存在多出口且配置了目標路由NAT,結果致使LocalDNS最終進行遞歸解析的時候的出口IP就有機率不爲本網的IP地址。
以下圖所示:
這樣的直接後果就是GSLB DNS收到的域名解析請求的來源IP仍是成了其它運營商的IP,最終致使用戶流量被導向了錯誤的IDC,用戶訪問變慢。
運營商的LocalDNS解析域名異常,給對用戶訪問騰訊互聯網業務的體驗形成了很是大的損害。
那麼之前,咱們是如何處理這些域名解析異常的問題的呢?
1)實時監控+商務推進:
這種方案是目前騰訊的運營團隊一直在使用的方案。這種方案就是週期比較長,畢竟經過行政手段來推進運營商來解決這個問題是比較耗時的。另外咱們經過大數據分析,得出的結論是Top 3的問題用戶均爲移動互聯網用戶。對於這部分用戶,咱們有什麼技術手段能夠解決以上的問題呢?
2)繞過自動分配DNS,使用114dns或Google public DNS:
這個方案看上去很美好,114dns是國內最大的中立緩存DNS,而Google又是秉承不做惡理念的互聯網工程帝國巨鱷,並且騰訊的權威DNS又支持edns-client-subnet功能,能直接識別使用Google publicDNS解析騰訊域名的用戶的IP地址,不會出現流量調度失效。
可是問題來了:
a. 如何在用戶側構造域名請求:對於PC端的客戶端來講,構造一個標準的DNS請求包並不算什麼難事。但在移動端要向一個指定的LocalDNS上發送標準的DNS請求包,並且要兼容各類iOS和android的版本的話,技術上是可行的,只是兼容的成本會很高;
b. 推進用戶修改配置極高:若是要推進用戶手動修改PC的DNS配置的話,在PC端和手機客戶端的WiFI下面還算勉強可行。可是要用戶修改在移動互聯網環境下的DNS配置,其難度不言而喻。
3)徹底拋棄域名,自建connectcenter進行流量調度:
若是要採用這種這種方案的話,首先你就得要拿到一份準確的IP地址庫來判斷用戶的歸屬,而後再製定個協議搭個connect center來作調度,而後再對接入層作調度改造。這種方案和2種方案同樣,不是不能作,只是成本會比較高,尤爲對於騰訊這種業務規模如此龐大的公司而言。
既然上面的這些傳統方案都存在那麼多的問題,那有沒有一種調度精準、成本低廉、配置方便的基於域名的流量調度系統呢?答案是確定的,咱們在下一步繼續分享。
HTTPDNS 利用 HTTP 協議與 DNS 服務器交互,代替了傳統的基於 UDP 協議的 DNS 交互,繞開了運營商的 Local DNS,有效防止了域名劫持,提升域名解析效率。另外,因爲 DNS 服務器端獲取的是真實客戶端 IP 而非 Local DNS 的 IP,可以精肯定位客戶端地理位置、運營商信息,從而有效改進調度精確性。
HTTPDNS的原理以下圖所示:
Local DNS 劫持:因爲 HttpDns 是經過 IP 直接請求 HTTP 獲取服務器 A 記錄地址,不存在向本地運營商詢問 domain 解析過程,因此從根本避免了劫持問題。
平均訪問延遲降低:因爲是 IP 直接訪問省掉了一次 domain 解析過程,經過智能算法排序後找到最快節點進行訪問。
用戶鏈接失敗率降低:經過算法下降以往失敗率太高的服務器排序,經過時間近期訪問過的數據提升服務器排序,經過歷史訪問成功記錄提升服務器排序。
通過努力,騰訊公司的GSLB 團隊推出的HttpDNS是爲移動客戶端量身定作的基於Http協議和域名解析的流量調度解決方案,專治LocalDNS解析異常以及流量調度不許。
詳細介紹以下。
騰訊的HttpDNS基本原理:
HttpDNS的原理很是簡單,主要有兩步:
A、客戶端直接訪問HttpDNS接口,獲取業務在域名配置管理系統上配置的訪問延遲最優的IP。(基於容災考慮,仍是保留次選使用運營商LocalDNS解析域名的方式);
B、客戶端向獲取到的IP後就向直接往此IP發送業務協議請求。以Http請求爲例,經過在header中指定host字段,向HttpDNS返回的IP發送標準的Http請求便可。
HttpDNS帶來的優點:
從原理上來說,HttpDNS只是將域名解析的協議由DNS協議換成了Http協議,並不複雜。
可是這一微小的轉換,卻帶來了無數的收益:
A、根治域名解析異常:因爲繞過了運營商的LocalDNS,用戶解析域名的請求經過Http協議直接透傳到了騰訊的HttpDNS服務器IP上,用戶在客戶端的域名解析請求將不會遭受到域名解析異常的困擾;
B、調度精準:HttpDNS能直接獲取到用戶IP,經過結合騰訊自有專利技術生成的IP地址庫以及測速系統,能夠保證將用戶引導的訪問最快的IDC節點上;
C、實現成本低廉:接入HttpDNS的業務僅須要對客戶端接入層作少許改造,無需用戶手機進行root或越獄;並且因爲Http協議請求構造很是簡單,兼容各版本的移動操做系統更不成問題;另外HttpDNS的後端配置徹底複用現有權威DNS配置,管理成本也很是低。總而言之,就是以最小的改形成本,解決了業務遭受域名解析異常的問題,並知足業務精確流量調度的需求;
D、擴展性強:HttpDNS提供可靠的域名解析服務,業務可將自有調度邏輯與HttpDNS返回結果結合,實現更精細化的流量調度。好比指定版本的客戶端鏈接請求的IP地址,指定網絡類型的用戶鏈接指定的IP地址等。
固然各位可能會問:用戶將首選的域名解析方式切換到了HttpDNS,那麼HttpDNS的高可用又是如何保證的呢?另外不一樣運營商的用戶訪問到同一個HttpDNS的服務IP,用戶的訪問延遲如何保證?
爲了保證高可用及提高用戶體驗,HttpDNS經過接入了騰訊公網交換平臺的BGP Anycast網絡,與全國多個主流運營商創建了BGP互聯,保證了這些運營商的用戶可以快速地訪問到HttpDNS服務;另外HttpDNS在多個數據中心進行了部署,任意一個節點發生故障時均能無縫切換到備份節點,保證用戶解析正常。
接入效果及將來展望:
當前騰訊的HttpDNS方案已在騰訊內部接入了多個業務,覆蓋數億用戶,並已持續穩定運行超過一年時間。而接入了HttpDNS的業務在用戶訪問體驗方面都有了很是大的提高。
以某個接入HttpDNS的業務爲例,該業務僅經過接入HttpDNS,在未作任何其它優化的狀況下,用戶平均訪問延遲降低超過10%,訪問失敗率降低了超過五分之一,用戶訪問體驗的效果提高很是顯著。另外騰訊的HttpDNS服務除了在騰訊內部被普遍使用之外,也受到了業務同行的確定。國內最大的publicDNS服務商114dns在受到騰訊DNS的啓發下,也推出了HttpDNS服務。
在將來的日子裏,騰訊GSLB團隊將會在騰訊內部進一步推廣HttpDNS服務,並將在實際業務的需求下對HttpDNS服務進行升級,如提供更爲通用、安全、簡單的接入協議,進一步提高接入用戶的網絡訪問體驗等等。但願HttpDNS能爲各位在解決域名解析異常及全局流量調度失效方面提供一個簡單、可行的思路。
做爲創業團隊,人力、財力、技術力量可能都無暇顧及這一塊,可是移動端APP卻實實在在面臨文中提到的各類DNS問題,咱們該怎麼辦呢?
目前,國內有一部分廠商已經提供了這個解析服務,能夠直接使用第三方服務。
目前,提供 HttpDns 解析服務的第3方服務商越來多,好比:阿里雲HttpDNS、騰訊雲HttpDNS、華爲雲HttpDNS等。
以阿里雲的 HttpDNS爲便,它的API 比較標準,直接發一個 Get 請求,帶上請求參數,返回結果以 json 返回:
http://203.107.1.1/d?host=www.52im.net
請求成功時,返回結果以下:
{
"host": "www.linkedkeeper.com",
"ips": [
"115.238.23.241",
"115.238.23.251"
],
"ttl": 57
}
在移動端,將由 HttpDns 得到的 IP 地址在原有 URL 的基礎上,將域名替換爲 IP,而後用新的 URL 發起 HTTP 請求。
HTTPDNSLib的Github地址:https://github.com/CNSRE/HTTPDNSLib
HTTPDNSLib中實現的HttpDNS交互流程原理:
從上圖中能夠看出來 整個業務的交互流程,用戶向查詢模塊傳入一個URL地址,而後查詢模塊會檢查緩存是否存在,不存在從httpdnsapi接口查詢, 而後通過評估模塊返回。在用戶請求URL過程完畢時,須要將此次請求的結果反饋給 lib庫的評估模塊由評估模塊入庫記錄本次質量數據。
HttpDns Lib庫交互詳細流程:
上圖這張詳細流程圖就更深刻的說了下 lib的工做原理。有兩條豎線講圖片分爲了三個區域,分別是左部分、中間部分 和 右部分。
左部分是app主線程操做的事情,中間部分是app調用者線程中處理lib庫事件邏輯的事情,右面部分是新線程獨立處理事件的邏輯。
開始是裏客戶端調用方,傳入一個 url,獲取domain信息後由查詢模塊查詢domain記錄,查詢模塊會從內存緩存層查詢,內存緩存層沒有數據會,查詢數據庫,若是數據庫也沒有數據會請求本地 LocalDNS。從三個環節中任何一個環節拿到數據後, 都會進入下一個環節,若是沒有拿到數據返回null結束。進入評估模塊,根據五個插件進行排序, 排序後返回數據給客戶端。
lib模塊設定定時器,根據ttl過時時間來檢查domain是否須要更新。 定時器是獨立線程, 不會影響app主線程。 httpdns api請求數據, 先從本身配置的 httpdns api接口獲取數據,若是獲取不到會從 dnspod api接口獲取若是也獲取不到 直接從本地 localDNS獲取數據,(從本地localDNS獲取數據後期會改成發送UDP包封裝dns協議從公共dns服務器直接獲取,好比114dns等。dns服務器地址可自行設定。 )獲取到數據後進入測速模塊。 測速模塊最新版本能夠配置兩種方式,一種是http空請求。 兩個http頭的交互,相似tcp首保耗時時間原理 ,用來測試鏈路最快。 另外一種是ping命令,(icmp協議)來儘可能最小化流量的消耗,考慮倒可能有的服務器禁ping就使用空http測速便可。 測速後將數據插入本地 cache 便可。
下面是測試Demo的截圖:
有關HttpDns Lib庫的詳細介紹,請見:《App域名劫持之DNS高可用 - 開源版HttpDNS方案詳解》。
《技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)》
《通俗易懂-深刻理解TCP協議(下):RTT、滑動窗口、擁塞處理》
《理論聯繫實際:Wireshark抓包分析TCP 3次握手、4次揮手過程》
《P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介》
《P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解》
《P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解》
《高性能網絡編程(一):單臺服務器併發TCP鏈接數到底能夠有多少》
《高性能網絡編程(二):上一個10年,著名的C10K併發鏈接問題》
《高性能網絡編程(三):下一個10年,是時候考慮C10M併發問題了》
《高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索》
《高性能網絡編程(五):一文讀懂高性能網絡編程中的I/O模型》
《高性能網絡編程(六):一文讀懂高性能網絡編程中的線程模型》
《鮮爲人知的網絡編程(一):淺析TCP協議中的疑難雜症(上篇)》
《鮮爲人知的網絡編程(二):淺析TCP協議中的疑難雜症(下篇)》
《鮮爲人知的網絡編程(三):關閉TCP鏈接時爲何會TIME_WAIT、CLOSE_WAIT》
《鮮爲人知的網絡編程(七):如何讓不可靠的UDP變的可靠?》
《網絡編程懶人入門(五):快速理解爲何說UDP有時比TCP更有優點》
《網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門》
《網絡編程懶人入門(八):手把手教你寫基於TCP的Socket長鏈接》
《網絡編程懶人入門(九):通俗講解,有了IP地址,爲什麼還要用MAC地址?》
《技術掃盲:新一代基於UDP的低延時網絡傳輸層協議——QUIC詳解》
《現代移動端網絡短鏈接的優化手段總結:請求速度、弱網適應、安全保障》
《移動端IM開發者必讀(一):通俗易懂,理解移動網絡的「弱」和「慢」》
《移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結》
《從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路》
《腦殘式網絡編程入門(一):跟着動畫來學TCP三次握手和四次揮手》
《腦殘式網絡編程入門(二):咱們在讀寫Socket時,究竟在讀寫什麼?》
《腦殘式網絡編程入門(三):HTTP協議必知必會的一些知識》
《腦殘式網絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push)》
《腦殘式網絡編程入門(五):天天都在用的Ping命令,它究竟是什麼?》
《腦殘式網絡編程入門(六):什麼是公網IP和內網IP?NAT轉換又是什麼鬼?》
《以網遊服務端的網絡接入層設計爲例,理解實時通訊的技術挑戰》
《全面瞭解移動端DNS域名劫持等雜症:技術原理、問題根源、解決方案等》
>> 更多同類文章 ……
(本文同步發佈於:http://www.52im.net/thread-2121-1-1.html)