百度App網絡深度優化系列《一》DNS優化

1、前言

網絡優化是客戶端幾大技術方向中公認的一個深度領域,因此百度App給你們帶來網絡深度優化系列文章,其中包含系列《一》DNS優化,系列《二》鏈接優化,系列《三》弱網優化,但願對你們在網絡方向的學習和實踐有所幫助。
百度起家於搜索,整個公司的網絡架構和部署都是基於標準的internet協議,目前已是全棧HTTPS,來到移動互聯網時代後,總的基礎架構不變,但在客戶端上須要作不少優化工做。
DNS(Domain Name System),它的做用是根據域名查出IP地址,它是HTTP協議的前提,只有將域名正確的解析成IP地址後,後面的HTTP流程才能進行,因此通常作網絡優化會首選優化DNS。html

2、背景

DNS優化核心須要解決的問題有兩點:
【1】因爲DNS劫持或故障形成的服務不可用,進而影響用戶體驗,影響公司的收入。
【2】因爲DNS調度不許確致使的性能退化,進而影響用戶體驗。
百度App承載着億級流量,每一年都會遇到運營商DNS劫持或運營商DNS故障,總體影響很是很差,因此DNS優化刻不容緩,經過下圖會更直觀的瞭解運營商劫持或故障的原理.jpgandroid

3、HTTPDNS

既然咱們面臨這麼嚴峻的問題,那麼咱們如何優化DNS呢?答案就是HTTPDNS。
大部分標準DNS都是基於UDP與DNS服務器交互的,HTTPDNS則是利用HTTP協議與DNS服務器交互,繞開了運營商的Local DNS服務,有效防止了域名劫持,提升域名解析效率,下圖是HTTPDNS的原理。
HTTPDNS的原理.jpgios

百度App HTTPDNS端上的實現是基於百度SYS團隊的HTTPDNS服務,下圖介紹了HTTPDNS的服務端部署結構。
HTTPDNS的服務端部署結構.jpggit

HTTPDNS服務是基於BGP接入的,BGP英文Border Gateway Protocol,即邊界網關協議,是一種在自治系統之間動態的交換路由信息的路由協議,BGP能夠根據當前用戶的運營商路由到百度服務點的對應集羣上,對於第三方域名,服務點會經過百度部署在運營商的CDN節點向其餘域名權威DNS發起查詢,查詢這個運營商下域名的最優IP。
百度App獨立實現了端的HTTPDNS SDK,下圖介紹了端HTTPDNS的總體架構。
端HTTPDNS的總體架構.jpggithub

DNS接口層:

DNS接口層解決的問題是屏蔽底層的細節,對外提供簡單整潔的API,下降使用者的上手成本,提升開發效率。算法

DNS策略層:

DNS策略層經過多種策略的組合,使HTTPDNS服務在性能,穩定性,可用性上均保持較高的水準,下面講解下每一個策略設計的初衷和具體實現緩存

1.容災策略

這是一個很是關鍵的策略,主要解決HTTPDNS服務可用性的問題,實踐證實,這個策略幫助百度App在異常狀況下挽救回不少流量。安全

【1】當HTTPDNS服務不可用而且本地也沒有緩存或者緩存失效的時候,會觸發降級策略,降級成運營商的localDNS方案,雖然存在運營商事故或者劫持的風險,但保障了DNS服務的可用性。服務器

【2】當HTTPDNS服務和localDNS服務雙雙不可用的狀況下,會觸發backup策略,使用端上的backup IP。微信

什麼是backup IP?backup IP是多組根據域名分類的IP列表,可雲端動態更新,方便後續運維同窗調整服務端的節點IP,不是全部域名都有對應的backup IP列表,目前百度App只能保證核心域名的可用性。

既然是一組IP,便有選取問題,backup IP選取機制是怎樣的呢?咱們的中心思想就是要在端上利用最小的代價,而且考慮服務端的負載均衡,獲得相對正確或者合理的選取結果。經過運營商和地理信息,能夠選擇一個相對較優的IP,但獲取地理信息須要很大耗時,外加頻次很高,代價很大,因此咱們選擇了RR算法來代替上面的方法(RR算法是Round-Robin,輪詢調度),這樣客戶端的代價下降到最小,服務端也實現了負載均衡。

2.安全策略

【1】HTTPDNS解決的核心問題就是安全,標準的DNS查詢大部分是基於UDP的,但也有基於TCP的,若是UDP被封禁,就須要使用TCP。無論是UDP仍是TCP,安全性都是沒有保障的,HTTPDNS查詢是基於標準的HTTP協議,爲了保證安全咱們會在HTTP上加一層TLS(安全傳輸層協議),這即是HTTPS。

【2】解決了傳輸層協議的安全性後,咱們要解決下域名解析的問題,上面咱們提到HTTPDNS服務是基於BGP接入的,在端上採用VIP方式請求HTTPDNS數據(VIP即Virtual IP,VIP並無與某設備存在一定的綁定關係,會跟隨主備切換之類的狀況發生而變換,VIP提供的服務是對應到某一臺或若干臺服務器的),既然請求原始數據須要使用IP直連的方式,那麼就擺脫了運營商localDNS的解析限制,這樣即便運營商出現了故障或者被劫持,都不會影響百度App的可用性。

3.任務調度策略

HTTPDNS服務提供了兩類HTTP接口,用於請求最優域名結果。第一種是多域名接口,針對不一樣的產品線,下發產品線配置的域名,第二種是單域名接口,只返回你要查詢的那個域名結果,這樣的設計和標準的DNS查詢基本是同樣的,只不過是從UDP協議變成了HTTP協議。

【1】多域名接口會在App冷啓動和網絡切換的時候請求一次,目的是在App的網絡環境初始化或者變化的時候預先獲取域名結果,這樣也會減小單域名接口的請求次數。

【2】單域名接口會在本地cache過時後,由用戶的操做觸發網絡請求,進而作一次單域名請求,用戶此次操做的DNS結果會降級成localDNS的結果,但在沒有過時的狀況下,下次會返回HTTPDNS的結果。

4.IP選取策略

IP選取策略解決的核心問題是最優IP的選取,避免由於接入點的選取錯誤形成的跨運營商耗時。HTTPDNS服務會將最優IP按照順序下發,客戶端默認選取第一個,這裏沒有作客戶端的連通性校驗的緣由,主要仍是擔憂端上的性能問題,不過有容災策略兜底,綜合評估仍是能夠接受的。

5.緩存策略

你們對於DNS緩存並不陌生,它主要是爲了提高訪問效率,操做系統,網絡庫等都會作DNS緩存。

DNS緩存中一個重要的概念就是TTL(Time-To-Live),在localDNS中針對不一樣的域名,TTL的時間是不同的,在HTTPDNS中這個值由服務端動態下發,百度App目前全部的域名TTL的配置是5分鐘,過時後若是沒有新的IP將繼續沿用老的IP,固然也能夠選擇不沿用老的IP,而降級成localDNS的IP,那麼這就取決於localDNS對於過時IP的處理。

6.命中率策略

若是HTTPDNS的命中率是100%,在保證HTTPDNS服務穩定高效的前提下,咱們就能夠作到防劫持,提高精準調度的能力。

【1】爲了提高HTTPDNS的命中率,咱們選擇使用多域名接口,在冷啓動和網絡切換的時候,批量拉取域名結果並緩存在本地,便於接下來的請求使用。

【2】爲了再一次提高HTTPDNS的命中率,當用戶操做觸發網絡請求,獲取域名對應的IP時,會提早進行本地過時時間判斷,時間是60s,若是過時,會發起單域名的請求並緩存起來,這樣會持續延長域名結果的過時時間。本地過時時間與上面提到的TTL是客戶端和服務端的雙重過時時間,目的是在異常狀況下能夠雙重保證過時時間的準確性。

基礎能力層:

基礎能力層主要提供給DNS策略層所須要的基礎能力,包括IPv4/IPv6協議棧探測的能力,數據傳輸的能力,緩存實現的能力,下面將講解每種能力的具體實現

1.IPv4/IPv6協議棧探測:

百度App的IPv6改造正在如火如荼的進行中,端上在HTTPDNS的IP選取上如何知道目前屬於哪一個協議棧成爲關鍵性問題,而且這種判斷要求性能極高,由於IP選取的頻次實在是過高了。

咱們選取的方案是UDP Connect,那麼何爲UDP Connect?你們都知道TCP是面向鏈接的,傳輸數據前客戶端都要調用connect方法經過三次握手創建鏈接,UDP是面向無鏈接的,無需創建鏈接便能收發數據,可是若是咱們調用了UDP的connect方法會發生什麼呢?當咱們調用UDP的connect方法時,系統會檢測其端口是否可用,地址是否正確,而後記錄對端的IP地址和端口號,返回給調用者,因此UDP Connect不會像TCP Connect發起三次握手,發生網絡真實損耗,UDP客戶端只有調用send或者sendto方法後纔會真正發起真實網絡損耗。
UDP Connect原理.jpg
有了UDP Connect的基礎保障,咱們在上層作了緩存機制,用來減小系統調用的損耗,時機上目前僅在冷啓動和網絡切換會觸發探測,在同一種網絡制式下探測一次基本能夠確保當前網絡是IPv4棧仍是IPv6棧。

目前百度App客戶端對於IPv4/IPv6雙棧的策略是保守的,僅在IPv6-only的狀況下使用v6的IP,其他使用的都是v4的IP,雙棧下的方案後續須要優化,業內目前標準的作法是happy eyeball算法,什麼叫happy eyeball呢?就是不會由於IPv4或IPv6的故障問題,致使用戶的眼球一直在等待加載或者出錯,這就是happy eyeball名字的由來。happy eyeball有v1版本RFC6555和v2版本RFC8305,前者是Cisco提出來的,後者是蘋果提出來的。happy eyeball解決的核心問題是,複雜環境下v4和v6 IP選取的問題,它是一套總體解決方案,對於域名查詢的處理,地址的排序,鏈接的嘗試等方面均作出了規定,感興趣的同窗能夠查看參考資料裏的【5】和【6】。

2.數據傳輸:

數據傳輸主要提供網絡請求的能力和數據解析的能力。

【1】網絡請求失敗重試的機制,獲取HTTPDNS結果的成功率會大大影響HTTPDNS的命中率,因此客戶端會有一個三次重試的機制,保障成功率。

【2】數據解析異常的機制,若是獲取的HTTPDNS的結果存在異常,將不會覆蓋端上的緩存。

3.緩存實現:

緩存的實現基本能夠分爲磁盤緩存和內存緩存,對於HTTPDNS的緩存場景,咱們是選其一仍是都選擇呢?百度App選擇的是內存緩存,目的是防止咱們本身的服務出現問題,運維同窗在緊急狀況下切換流量,若是作了磁盤緩存,會致使百度App在重啓後也可能不可用,但這種問題會致使APP在冷啓動期間,HTTPDNS結果未返回前,仍是存在故障或者劫持的風險,綜合評估來看能夠接受,若是出現這種極端狀況,影響的是冷啓動階段的一些請求,但只要HTTPDNS結果返回後便會恢復正常。

4、HTTPDNS的最佳實踐

百度App目前客戶端網絡架構因爲歷史緣由還未統一,不過咱們正朝着這個目標努力,下面着重介紹下HTTPDNS在Android和iOS網絡架構中的位置及實踐。

HTTPDNS在Android網絡架構的位置及實踐

百度App的Android網絡流量都在okhttp之上,上層進行了網絡門面的封裝,封裝內部的實現細節和對外友好的API,供各個業務和基礎模塊使用,在okhttp上咱們擴展了DNS模塊,使用HTTPDNS替換了原有的系統DNS。
HTTPDNS在Android網絡架構的位置.jpg

HTTPDNS在iOS網絡架構的位置及實踐

百度App的iOS網絡流量都在cronet(chromium的net模塊)之上,上層咱們使用AOP的方式將cronet stack注入進URLSession裏,這樣咱們就能夠直接使用URLSession的API進行網絡的操做並且更易於系統維護,在上層封裝了網絡門面,供各個業務和基礎模塊使用,在cronet內部咱們修改了DNS模塊,除了原有的系統DNS邏輯外,還添加了HTTPDNS的邏輯。iOS上還有一部分流量是在原生URLSession上,主要是有些第三方業務沒有使用cronet但還想單獨使用HTTPDNS的能力,因此就有了下面的HTTPDNS封裝層,方法是在上層直接將域名替換成IP,域名對於底層不少機制是相當重要的,好比https校驗,cookie,重定向,SNI(Server Name Indication)等,因此將域名修改爲了IP直連後,咱們又處理了以上三種狀況,保證請求的可用性。
HTTPDNS在iOS網絡架構的位置.jpg

5、收益

DNS優化的收益主要有兩點,一是防止DNS的劫持(在出問題時顯得尤其重要),下降網絡時延(在調度不許確的狀況下,會增大網絡的時延,下降用戶的體驗),這兩點收益須要結合業務來講,以百度App Feed業務爲例,第一點上咱們取得了比較大的效果,iOS劫持率由0.12%下降到0.0002%,Android劫持率由0.25%下降到0.05%,第二點的收益不明顯,緣由在於Feed業務主要目標羣體在國內,百度在國內節點佈局相對豐富,服務總體質量也較高,即便出現調度不許確的狀況,差值也不會太大,但若是在國外狀況可能會差不少。

6、結語

DNS優化是個持續性的話題,上面介紹的百度App的一些經驗和作法並不見得完美,但咱們會持續深刻的優化下去,爲百度App的DNS能力保駕護航。最後感謝你們的辛苦閱讀,但願對你有所幫助,後面會繼續推出-百度App網絡深度優化系列《二》鏈接優化,敬請期待。

7、我的心得

作爲一個工程師,如何才能作好網絡優化這件事情,是個值得咱們交流探討的話題,我的認爲應該從如下五方面入手。

【1】基礎知識要了解學習,要夯實,網絡相關的內容不少,很雜,不易學習,啃過IETF發佈的RFC的同窗應該深有感觸。

【2】學會將看不見的網絡變成看得見的,不少自認爲對於網絡很瞭解的同窗,動不動就背誦tcp協議原理,擁塞控制算法,滑動窗口大小等,但真正遇到線上問題,無從下手。對於客戶端同窗,咱們在PC上要學會使用tcpdump和Wireshark等工具,適當使用Fiddler和Charles等工具,不少時候電腦和手機的網絡環境不見得一致,因此要在手機上使用iNetTools,Ping&DNS或終端工具。學會使用工具後,要學着創造不一樣的網絡環境,有不少工具能幫助你完成這點,好比蘋果的Network Link Conditioner,FaceBook的ATC(Augmented Traffic Control)等。具有以上兩個場景後,你的第一條儲備就發揮了做用,你要能看懂握手過程,傳輸過程,異常斷開過程等。

【3】有了以上兩點的準備,接下來須要一個會出現各類網絡問題的平臺,給你積累經驗,讓一個個高壓下的線上問題錘鍊你,折磨你。

【4】網絡優化是須要數據支撐的,但數據的採集和分析是須要經驗的,有些數據一眼看下去就是不靠譜的,有些數據怎麼分析都是負向收益的,通常來講是有三重奏來對數據進行分析的,一,線下數據的採集和分析,得出正向收益,二,灰度數據的採集和分析,得出正向收益,三,線上數據的採集和分析,得出正向收益。

【5】數據的正向收益,不能徹底證實提高了用戶的體驗,因此不少時候須要針對特定場景,特定case來分析和優化,就算是你們公認作的很好的微信,也不是在全部場景下都能保證體驗上的最佳。

8、參考資料


本文做者:
蔡銳


在微信-搜索頁面中輸入「百度App技術」,便可關注微信官方帳號;或使用微信識別如下二維碼,亦可關注。
微信連接.jpg

相關文章
相關標籤/搜索