Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 156, comments - 13, trackbacks - 0, articles - 0

本文由百度技術團隊“蔡銳”原創發表于“百度App技術”公眾號,原題為《百度App網絡深度優化系列《一》DNS優化》,感謝原作者的無私分享。

一、前言

網絡優化是客戶端幾大技術方向中公認的一個深度領域,所以百度App給大家帶來網絡深度優化系列文章。

本系列文章目錄如下:

  • 百度APP移動端網絡深度優化實踐分享(一):DNS優化篇》(* 本文)
  • 百度APP移動端網絡深度優化實踐分享(二):網絡連接優化篇
  • 《百度APP移動端網絡深度優化實踐分享(三):移動端弱網優化篇》
  • 希望對大家在網絡方向的學習和實踐有所幫助。

    百度起家于搜索,整個公司的網絡架構和部署都是基于標準的internet協議,目前已經是全棧HTTPS,來到移動互聯網時代后,總的基礎架構不變,但在客戶端上需要做很多優化工作。

    DNS(Domain Name System),它的作用是根據域名查出IP地址,它是HTTP協議的前提,只有將域名正確的解析成IP地址后,后面的HTTP流程才能進行,所以一般做網絡優化會首選優化DNS。

    (本文同步發布于:http://www.52im.net/thread-2472-1-1.html

    二、相關文章

    TCP/IP詳解 卷1:協議 - 第14章 DNS:域名系統
    全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等
    美圖App的移動端DNS優化實踐:HTTPS請求耗時減小近半
    現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障
    移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”
    移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結

    三、技術背景

    DNS優化核心需要解決的問題有兩點:

    1)由于DNS劫持或故障造成的服務不可用,進而影響用戶體驗,影響公司的收入;

    2)由于DNS調度不準確導致的性能退化,進而影響用戶體驗。

    百度App承載著億級流量,每年都會遇到運營商DNS劫持或運營商DNS故障,整體影響非常不好,所以DNS優化刻不容緩,通過下圖會更直觀的了解運營商劫持或故障的原理。

    ▲ 運營商劫持或故障的原理

    有關移動端DNS劫持等各種疑難雜癥,詳見文章《全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等》。

    四、HTTPDNS

    4.1 概述

    既然我們面臨這么嚴峻的問題,那么我們如何優化DNS呢?答案就是HTTPDNS。

    大部分標準DNS都是基于UDP與DNS服務器交互的,HTTPDNS則是利用HTTP協議與DNS服務器交互,繞開了運營商的Local DNS服務,有效防止了域名劫持,提高域名解析效率,下圖是HTTPDNS的原理。

    ▲ HTTPDNS原理

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

    ▲ HTTPDNS部署結構

    HTTPDNS服務是基于BGP接入的,BGP英文Border Gateway Protocol,即邊界網關協議,是一種在自治系統之間動態的交換路由信息的路由協議,BGP可以根據當前用戶的運營商路由到百度服務點的對應集群上,對于第三方域名,服務點會通過百度部署在運營商的CDN節點向其他域名權威DNS發起查詢,查詢這個運營商下域名的最優IP。

    百度App獨立實現了端的HTTPDNS SDK,下圖介紹了端HTTPDNS的整體架構。

    ▲ 端HTTPDNS的整體架構

    更多HTTPDNS的資料,請見:《全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等》、《美圖App的移動端DNS優化實踐:HTTPS請求耗時減小近半》。

    4.2 DNS接口層

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

    4.3 DNS策略層

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

    【4.3.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,輪詢調度),這樣客戶端的代價降低到最小,服務端也實現了負載均衡。

    【4.3.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的可用性。

    【4.3.3 任務調度策略】:

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

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

    (2)單域名接口會在本地cache過期后,由用戶的操作觸發網絡請求,進而做一次單域名請求,用戶這次操作的DNS結果會降級成localDNS的結果,但在沒有過期的情況下,下次會返回HTTPDNS的結果。

    【4.3.4 IP選取策略】:

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

    【4.3.5 緩存策略】:

    大家對于DNS緩存并不陌生,它主要是為了提升訪問效率,操作系統,網絡庫等都會做DNS緩存。

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

    【4.3.6 命中率策略】:

    如果HTTPDNS的命中率是100%,在保證HTTPDNS服務穩定高效的前提下,我們就可以做到防劫持,提升精準調度的能力。

    (1)為了提升HTTPDNS的命中率,我們選擇使用多域名接口,在冷啟動和網絡切換的時候,批量拉取域名結果并緩存在本地,便于接下來的請求使用。

    (2)為了再一次提升HTTPDNS的命中率,當用戶操作觸發網絡請求,獲取域名對應的IP時,會提前進行本地過期時間判斷,時間是60s,如果過期,會發起單域名的請求并緩存起來,這樣會持續延長域名結果的過期時間。本地過期時間與上面提到的TTL是客戶端和服務端的雙重過期時間,目的是在異常情況下可以雙重保證過期時間的準確性。

    4.4 基礎能力層

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

    【4.4.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原理

    有了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】。

    【4.4.2 數據傳輸】:

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

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

    (2)數據解析異常的機制,如果獲取的HTTPDNS的結果存在異常,將不會覆蓋端上的緩存。

    【4.4.3 緩存實現】:

    緩存的實現基本可以分為磁盤緩存和內存緩存,對于HTTPDNS的緩存場景,我們是選其一還是都選擇呢?

    百度App選擇的是內存緩存,目的是防止我們自己的服務出現問題,運維同學在緊急情況下切換流量,如果做了磁盤緩存,會導致百度App在重啟后也可能不可用,但這種問題會導致APP在冷啟動期間,HTTPDNS結果未返回前,還是存在故障或者劫持的風險,綜合評估來看可以接受,如果出現這種極端情況,影響的是冷啟動階段的一些請求,但只要HTTPDNS結果返回后便會恢復正常。

    五、HTTPDNS的最佳實踐

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

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

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

    ▲ HTTPDNS在Android網絡架構的位置

    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網絡架構的位置

    六、實際收益

    DNS優化的收益主要有兩點:

    1)防止DNS的劫持(在出問題時顯得尤為重要);

    2)降低網絡時延(在調度不準確的情況下,會增大網絡的時延,降低用戶的體驗)。

    這兩點收益需要結合業務來說,以百度App Feed業務為例:

    1)第一點上我們取得了比較大的效果,iOS劫持率由0.12%降低到0.0002%,Android劫持率由0.25%降低到0.05%;

    2)第二點的收益不明顯,原因在于Feed業務主要目標群體在國內,百度在國內節點布局相對豐富,服務整體質量也較高,即使出現調度不準確的情況,差值也不會太大,但如果在國外情況可能會差很多。

    七、本文結語

    DNS優化是個持續性的話題,上面介紹的百度App的一些經驗和做法并不見得完美,但我們會持續深入的優化下去,為百度App的DNS能力保駕護航。最后感謝大家的辛苦閱讀,希望對你有所幫助,后面會繼續推出《百度APP移動端網絡深度優化實踐分享(二):網絡連接優化篇》,敬請期待。

    八、個人心得

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

    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來分析和優化,就算是大家公認做的很好的微信,也不是在所有場景下都能保證體驗上的最佳。

    九、參考資料

    [1] https://chromium.googlesource.com/chromium/src/+/HEAD/docs/android_build_instructions.md

    [2] https://chromium.googlesource.com/chromium/src/+/HEAD/docs/ios/build_instructions.md

    [3] https://github.com/Tencent/mars

    [4] https://tools.ietf.org/html/rfc7858

    [5] https://tools.ietf.org/html/rfc6555

    [6] https://tools.ietf.org/html/rfc8305

    (原文鏈接:點此進入

    附錄:更多網絡通信方面的精華文章

    TCP/IP詳解 - 第11章·UDP:用戶數據報協議
    TCP/IP詳解 - 第17章·TCP:傳輸控制協議
    TCP/IP詳解 - 第18章·TCP連接的建立與終止
    TCP/IP詳解 - 第21章·TCP的超時與重傳
    技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)
    通俗易懂-深入理解TCP協議(上):理論基礎
    通俗易懂-深入理解TCP協議(下):RTT、滑動窗口、擁塞處理
    理論經典:TCP協議的3次握手與4次揮手過程詳解
    理論聯系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程
    計算機網絡通訊協議關系圖(中文珍藏版)
    UDP中一個包的大小最大能多大?
    P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介
    P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解
    P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解
    通俗易懂:快速理解P2P技術中的NAT穿透原理
    高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少
    高性能網絡編程(二):上一個10年,著名的C10K并發連接問題
    高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了
    高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索
    高性能網絡編程(五):一文讀懂高性能網絡編程中的I/O模型
    高性能網絡編程(六):一文讀懂高性能網絡編程中的線程模型
    不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)
    不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)
    不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT
    不為人知的網絡編程(四):深入研究分析TCP的異常關閉
    不為人知的網絡編程(五):UDP的連接性和負載均衡
    不為人知的網絡編程(六):深入地理解UDP協議并用好它
    不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?
    不為人知的網絡編程(八):從數據傳輸層深度解密HTTP
    網絡編程懶人入門(一):快速理解網絡通信協議(上篇)
    網絡編程懶人入門(二):快速理解網絡通信協議(下篇)
    網絡編程懶人入門(三):快速理解TCP協議一篇就夠
    網絡編程懶人入門(四):快速理解TCP和UDP的差異
    網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢
    網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門
    網絡編程懶人入門(七):深入淺出,全面理解HTTP協議
    網絡編程懶人入門(八):手把手教你寫基于TCP的Socket長連接
    網絡編程懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?
    技術掃盲:新一代基于UDP的低延時網絡傳輸層協議——QUIC詳解
    讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享
    現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障
    聊聊iOS中網絡編程長連接的那些事
    移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”
    移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結
    IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)
    IPv6技術詳解:基本概念、應用現狀、技術實踐(下篇)
    從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路
    腦殘式網絡編程入門(一):跟著動畫來學TCP三次握手和四次揮手
    腦殘式網絡編程入門(二):我們在讀寫Socket時,究竟在讀寫什么?
    腦殘式網絡編程入門(三):HTTP協議必知必會的一些知識
    腦殘式網絡編程入門(四):快速理解HTTP/2的服務器推送(Server Push)
    腦殘式網絡編程入門(五):每天都在用的Ping命令,它到底是什么?
    腦殘式網絡編程入門(六):什么是公網IP和內網IP?NAT轉換又是什么鬼?
    以網游服務端的網絡接入層設計為例,理解實時通信的技術挑戰
    邁向高階:優秀Android程序員必知必會的網絡基礎
    全面了解移動端DNS域名劫持等雜癥:技術原理、問題根源、解決方案等
    美圖App的移動端DNS優化實踐:HTTPS請求耗時減小近半
    Android程序員必知必會的網絡通信傳輸層協議——UDP和TCP
    IM開發者的零基礎通信技術入門(一):通信交換技術的百年發展史(上)
    IM開發者的零基礎通信技術入門(二):通信交換技術的百年發展史(下)
    IM開發者的零基礎通信技術入門(三):國人通信方式的百年變遷
    IM開發者的零基礎通信技術入門(四):手機的演進,史上最全移動終端發展史
    IM開發者的零基礎通信技術入門(五):1G到5G,30年移動通信技術演進史
    IM開發者的零基礎通信技術入門(六):移動終端的接頭人——“基站”技術
    IM開發者的零基礎通信技術入門(七):移動終端的千里馬——“電磁波”
    IM開發者的零基礎通信技術入門(八):零基礎,史上最強“天線”原理掃盲
    IM開發者的零基礎通信技術入門(九):無線通信網絡的中樞——“核心網”
    IM開發者的零基礎通信技術入門(十):零基礎,史上最強5G技術掃盲
    IM開發者的零基礎通信技術入門(十一):為什么WiFi信號差?一文即懂!
    IM開發者的零基礎通信技術入門(十二):上網卡頓?網絡掉線?一文即懂!
    IM開發者的零基礎通信技術入門(十三):為什么手機信號差?一文即懂!
    IM開發者的零基礎通信技術入門(十四):高鐵上無線上網有多難?一文即懂!
    IM開發者的零基礎通信技術入門(十五):理解定位技術,一篇就夠
    百度APP移動端網絡深度優化實踐分享(一):DNS優化篇
    百度APP移動端網絡深度優化實踐分享(二):網絡連接優化篇
    >> 更多同類文章 ……

    (本文同步發布于:http://www.52im.net/thread-2472-1-1.html


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: [email protected], 聯系QQ: 413980957, 微信: hellojackjiang
    魔法糖果闯关 吉林11选5就是牛 彩运8骗局 香港六合彩网站 有条能赚钱的百科 澳洲幸运10群 贵州快3第1期几点开始 怎么样找内部优惠券赚钱 抢你妹赚钱 极速赛车怎么玩赢钱 pk10四码二期必中方法 电玩西游争霸 极速时时彩上必发彩票 黑彩11选5赚钱吗 北京pk10赛车选号技巧 平特一肖三期 中国足球网