Android高手筆記 - 網絡優化

  • 很難找到一款完全不需要網絡的應用,即使是單機應用,也會存在數據上報、廣告等各種各樣的網絡請求

網絡基礎

Http & Https

定義:
  1. https:Hypertext Transfer Protocol over Secure Socket Layer 超文本傳輸協議的安全套接字層
  2. http:一種詳細規定了瀏覽器和萬維網服務器之間互相通信的規則
區別:
  1. https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
  2. http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的SSL/TLS加密
    傳輸協議(在 HTTP 與 TCP 之間)。(SSL/TSL 的常見開源實現是 OpenSSL)
  3. http和https使用的是完全不同的連接方式,默認端口也不一樣,前者是80,后者是443。
  4. http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、
    身份認證的網絡協議,比http協議安全。
  5. 寫法上的區別是前綴的不同,客戶端處理的方式也不同;
SSL(Secure Sockets Layer)安全套接層
  • SSL 位于傳輸層與應用層之間,它是一個子層,作用主要有兩點:
  1. 數據安全(保證數據不會被泄漏)與數據完整(保證數據不會被篡改);
  2. 對數據進行加密后傳輸;
https目的:
  • 提供對網站服務器的身份認證,保護交換數據的隱私和完整性;
HTTPS 解決的問題:
  1. 信任主機問題(從CA申請證書);
  2. 防止通信過程中的數據的泄密和被篡改;
https實現原理:
  1. 客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
  2. Web服務器收到客戶端請求后,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
  3. 客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級(交換協議版本號),也就是信息加密的等級。
  4. 客戶端的瀏覽器根據雙方同意的安全等級,建立臨時會話密鑰,然后利用網站的公鑰將會話密鑰加密,
    并傳送給網站。
  5. Web服務器利用自己的私鑰解密出會話密鑰。
  6. Web服務器利用會話密鑰加密與客戶端之間的通信。

https加密原理

  • 相比較對稱加密而言,非對稱加密安全性更高,但是加解密耗費的時間更長,速度慢。
CA證書:

其實就是數字證書,是由 CA 機構頒發的,包括證書的頒發機構、版本,
使用者,公鑰,有效時間,數字簽名 Hash 值和簽名 Hash 算法;

客戶端如何校驗CA證書

CA 證書中的 Hash 值,其實是用證書的私鑰進行加密后的值(證書的私鑰不在 CA 證書
中)。然后客戶端得到證書后,利用證書中的公鑰去解密該 Hash 值,得到 Hash-a ;然
后再利用證書內的簽名 Hash 算法去生成一個 Hash-b 。最后比較 Hash-a 和 Hash-b 這
兩個的值。如果相等,那么證明了該證書是對的,服務端是可以被信任的;如果不相等,那
么就說明該證書是錯誤的,可能被篡改了,瀏覽器會給出相關提示,無法建立起 HTTPS 連
接。除此之外,還會校驗 CA 證書的有效時間和域名匹配等。

HTTPS中的SSL握手建立過程
  1. 客戶端和服務端建立 SSL 握手,客戶端通過 CA 證書來確認服務端的身份;
  2. 互相傳遞三個隨機數,之后通過這隨機數來生成一個密鑰;
  3. 互相確認密鑰,然后握手結束;
  4. 數據通訊開始,都使用同一個對話密鑰來加解密;
    (簡而言之,用非對稱加密算法生成對稱加密的秘鑰,用對稱加密算法加密通信內容)

分層:

OSI七層模型(物數網傳會表應)
  • 應用層: 為計算機用戶提供接口和服務。
  • 表示層: 數據處理:編解碼、加解密等等。
  • 會話層: 管理(建立、維護、重連)通信會話。
  • 傳輸層: 管理端到端的通信連接。
  • 網絡層: 數據路由:決定數據在網絡中的路徑。
  • 數據鏈路層: 管理相鄰節點之間的數據通信。
  • 物理層: 數據通信的光電物理特性。
TCP/IP 四層模型
  • 應用層:包括OSI中的會表應三層,HTTP,FTP,SMTP,POP3,NFS、DNS等協議都屬于應用層;
  • 傳輸層,TCP/UDP協議屬于傳輸層
  • 網絡層:IP協議屬于網絡層
  • 網絡接口層:包括OSI中的物數兩層,
HTTP(應用層)》》TSL/SSL(安全層)》》TCP(傳輸層)》》IP(網絡層)》》網絡接口(數據鏈路層)
DNS(Domain Name System) 域名系統服務
  • 通過把沒有規則的點分十進制 IP 地址轉換為可以理解的一些域名(域名通過 DNS 服務可以被轉換成 IP 地址。);
域名:
  • 可以分為頂級域、二級域、三級域...,例如:www.taobao.com => - 三級域.二級域.頂級域。
DHCP(Dynamic Host Configuratin Protocol) 動態主機設置協議
  • 網絡管理員只需配置一段共享的 IP 地址,每一臺新接入的機器都可以通過 DHCP 來這個共享的 IP 地址里面申請 IP 地址,就可以自動配置。等用完還回去其它機器也能使用;
  • DHCP 是一個局域網協議,是應用 UDP 協議的應用層協議;

為什么 TCP 要經過三次握手,四次揮手

三次握手:
  1. 第一次握手:建立連接。客戶端發送連接請求報文段,將 SYN 位置為 1,Sequence Number為 x;然后,客戶端進入 SYN_SEND 狀態,等待服務器的確認。
  2. 第二次握手:服務器收到 SYN 報文段。服務器收到客戶端的 SYN 報文段,需要對這個 SYN 報文段進行確認,設置 Acknowledgment Number 為 x+1(Sequence Number+1);同時,自己自己還要發送 SYN 請求信息,將 SYN 位置為 1,Sequence Number 為 y;服務器端將上述所有信息放到一個報文段(即 SYN+ACK 報文段)中,一并發送給客戶端,此時服務器進入 SYN_RECV 狀態;
  3. 第三次握手:客戶端收到服務器的 SYN+ACK 報文段。然后將 Acknowledgment Number設置為 y+1,向服務器發送 ACK 報文段,這個報文段發送完畢以后,客戶端和服務器端都進入 ESTABLISHED 狀態,完成 TCP 三次握手。
四次揮手
  1. 第一次分手:主機 1(可以使客戶端,也可以是服務器端),設置 Sequence Number 和Acknowledgment Number,向主機 2 發送一個 FIN 報文段;此時,主機 1 進入 FIN_WAIT_1狀態;這表示主機 1 沒有數據要發送給主機 2 了;
  2. 第二次分手:主機 2 收到了主機 1 發送的 FIN 報文段,向主機 1 回一個 ACK 報文段,Acknowledgment Number 為 Sequence Number 加 1;主機 1 進入 FIN_WAIT_2 狀態;主機 2 告訴主機 1,我“同意”你的關閉請求;
  3. 第三次分手:主機 2 向主機 1 發送 FIN 報文段,請求關閉連接,同時主機 2 進入 LAST_ACK狀態;
  4. 第四次分手:主機 1 收到主機 2 發送的 FIN 報文段,向主機 2 發送 ACK 報文段,然后主機1 進入 TIME_WAIT 狀態;主機 2 收到主機 1 的 ACK 報文段以后,就關閉連接;此時,主機1 等待 2MSL 后依然沒有收到回復,則證明 Server 端已正常關閉,那好,主機 1 也可以關閉連接了。(MSL是Maximum Segment Lifetime英文的縮寫,中文可以譯為“報文最大生存時間”,他是任何報文在網絡上存在的最長時間,超過這個時間報文將被丟棄);
  • “三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤”。主要目的防止 server 端一直等待,浪費資源。換句話說,即是為了保證服務端能收接受到客戶端的信息并能做出正確的應答而進行前兩次(第一次和第二次)握手,為了保證客戶端能夠接收到服務端的信息并能做出正確的應答而進行后兩次(第二次和第三次)握手。
  • “四次揮手”原因是因為 tcp 是全雙工模式,接收到 FIN 時意味將沒有數據再發來,但是還是可以繼續發送數據。
TCP 在三次握手的時候,IP 層和 MAC層在做什么?
  • TCP 每發送一個消息,都會帶著 IP 層和 MAC 層。因為 TCP 每發送一個消息,IP 層和 MAC 層的所有機制都要運行一遍。

TCP 和 UDP 的區別?

  1. TCP面向連接,UDP是無連接(即發送數據之前不需要建立連接);
  2. 對系統資源的要求(TCP 較多,UDP 少);
  3. UDP 程序結構較簡單,不會對數據報進行任何的處理,即不合并,也不拆分數據,直接將應用層數據塞進報文里面。
  4. UDP 通常用于多媒體信息分發,即視頻、語音、實時信息 等等。而 TCP 通常用于可靠信息的傳輸,應用場景包括金融交易、可靠通信、MQ 等等 ;
  5. TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;
    UDP沒有擁塞控制,盡最大努力交付,不管網絡是否擁塞,它都會把數據給交付出去,但不保證可靠交付
  6. UDP具有較好的實時性,工作效率比TCP高,適用于對高速傳輸和實時性有較高的通信或廣播通信。
  7. 每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信
  8. TCP是全雙工通信:兩個設備在連接時,它們都可以同時地發送數據與接收數據。
  9. TCP是面向字節流的協議(可能出現黏包問題),UDP面向報文傳輸
  10. TCP 首部開銷20字節;UDP 的首部開銷小,只有 8 個字節。
TCP 協議的可靠傳輸
  • TCP 的可靠傳輸基于連續 ARQ 協議。
  1. 滑動窗口
  2. 累積確認
  3. 選擇重傳
TCP 協議的流量控制
  • 流量控制指的是 讓發送方發送速率不要太快。TCP 使用了滑動窗口來實現流量控制。
  1. 滑動窗口: 接收方可以調整滑動窗口的大小來控制發送方發送數據的效率。
  2. 堅持定時器: 使用滑動窗口進行流量控制的時候設置:當接收到窗口為0的消息,則啟動堅持定時器;堅持定時器每隔一段時間發送一個窗口探測報文;
TCP 協議的擁塞控制
  • 不同于流量控制考慮的是點對點的通信量的控制,擁塞控制考慮的是整個網絡,是一個全局性的考慮。
  1. 慢啟動算法:由小到大逐漸增加發送數據量;每收到一個報文確認,就加一;超過慢啟動閾值(ssthresh) 則不再增長。
  2. 擁塞避免算法:維護一個擁塞窗口的變量;只要網絡不擁塞,就試探著將擁塞窗口調大。
  • TCP 的擁塞控制在前期使用了 慢啟動 算法對窗口大小進行指數增長,直到超過慢啟動閾值(ssthresh)則不再增長,后續則啟動擁塞避免算法對窗口進行線性增長。
TCP 協議的四個定時器
  1. 超時定時器;
  2. 堅持定時器;
  3. 時間等待定時器;
  4. 保活定時器:
TCP可靠傳輸原理實現
  1. 確認和重傳:接收方收到報文后就會進行確認,發送方一段時間沒有收到確認就會重傳。
  2. 數據校驗。
  3. 數據合理分片與排序: TCP 會對數據進行分片,接收方會緩存為按序到達的數據,重新排序后再提交給應用層。
  4. 流程控制:當接收方來不及接收發送的數據時,則會提示發送方降低發送的速度,防止包丟失。
  5. 擁塞控制:當網絡發生擁塞時,減少數據的發送。
    (http://blog.chinaunix.net/uid-26275986-id-4109679.html)

IP 協議

  • 物理設備通過使用 IP 協議,屏蔽了物理網絡之間的差異;
作用
  1. IP 協議 使得復雜的實際網絡變為一個虛擬互連的網絡;
  2. IP 協議 使得網絡層可以屏蔽底層細節而專注網絡層的數據轉發;
  3. IP 協議 解決了在虛擬網絡中數據報傳輸路徑的問題;
IP 地址
  • 每一個唯一的網絡設備都有一個唯一的 IP 地址。不同于 MAC 地址是不可改變的,IP 地址會根據當前設備所連接的網絡環境的變化而發生變化。
MAC 地址與 IP 地址的區別
  1. 數據幀每一跳的 MAC 地址都在變化,而IP 數據報每一跳的 IP 地址始終不變。
  2. IP 地址具有遠程定位功能,而 MAC 地址更像是身份證號,它的唯一性是為了組網時可以不用擔心不同的網卡在一個網絡里會產生沖突,從硬件角度保證不同的網卡有不同的標識。
  3. 相比于 IP 地址,MAC 地址的通信范圍比較小,局限在一個子網里。例如:從 192.168.0.1/24 訪問 192.168.0.9/24 是可以用 MAC 地址的。
ARP(Address Resolution Protocol)地址解析協議
  • 將網絡層 IP 32位地址轉換為數據鏈路層 MAC 48位地址。
  • ARP 協議被直接封裝在了數據鏈路層中的數據幀里面的。
RARP(Reverse Address Resolutioni Protocol)逆地址解析協議
  • 將數據鏈路層 MAC 48位地址轉換為網絡層 IP 32位地址
  • 除了類型 8035 標識為 RARP 協議,其它內容與 ARP 協議類似。
網絡地址轉換 NAT(Network Address Translationn) 技術
  • 不改變 IP 地址的網關,我們稱為轉發網關;改變 IP 地址的網關,我們稱為 NAT 網關。
  • 使用 NAT ,它用于多個主機通過一個公有 IP 訪問互聯網的私有網絡,并減緩了 IP 地址的消耗,但是增加了網絡通信的復雜度。
  • 為什么要使用 NAT?
    1. IPv4 最多只有40+億個 IP 地址。
    2. 早期 IP 地址的不合理規劃導致 IP 號浪費。
內網地址
  • 內部機構使用, 避免與外網地址重復。
三類內網地址:
  1. A 類:10.0.0.0~10.255.255.255(支持千萬數量級設備)。
  2. B 類:172.16.0.0~172.31.255.255(支持百萬數據級設備)。
  3. C 類:192.168.0.0~192.168.255.255(支持萬數量級設備)。
ICMP(Internet Control Message Protocol)協議
  • ICMP 協議主要是用于 輔助 IP 協議發送與接收數據的,它可以報告錯誤信息或異常情況。
應用:使用 Ping 命令對網絡故障進行排查
  1. ping 回環地址 127.0.0.1,不通,說明計算機使用的協議棧有問題,需要重裝系統或協議棧。
  2. Ping 網關地址(路由地址),內網 ping 192.168.0.1/ 192.168.1.1,通,說明本機到路由器的地址是通的。不通,則說明 WIFI、網線是有問題的。
  3. Ping 遠端地址 ping www.wanandroid.com,不通,則說明家中到 ISP 的網絡之間是有故障的。這個時候就要從電信、聯通、移動等 ISP 來排查問題了。
路由
  • 路由表: 包括了目的IP地址與下一跳IP地址的映射關系;

GET 和 POST 的區別

  1. get參數通過url傳遞,post放在request body中。
  2. get請求在url中傳遞的參數是有長度限制的,而post沒有。
  3. get比post更不安全,因為參數直接暴露在url中,所以不能用來傳遞敏感信息。
  4. get請求只能進行url編碼,而post支持多種編碼方式。
  5. get請求會瀏覽器主動cache,請求參數會被完整保留在瀏覽歷史記錄里,而post中的參數不會被保留。
  6. GET和POST本質上就是TCP鏈接,并無差別。但是由于HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同。

無線網絡

  • 網絡的分類:按作用范圍分為廣域網,城域網,局域網;按使用者可分為公用網絡,專用網絡;按傳輸介質分為有線網絡,無線網絡;
  • 有線通信:在實體物質上傳播,使用銅線、光纖等有線介質
  • 無線通信:利用電磁波進行通信,常用的無線網絡類型:WiFi、蜂窩網絡、藍牙、NFC;
  • 無線網絡的瓶頸:單條光纖最大速度已達到了26Tbps,目前主流的移動通信標準,4G LTE,理論速率只有150Mbps(不包括載波聚合)。
    這個和有線是完全沒辦法相比的,所以,5G如果要實現端到端的高速率,重點是突破無線這部分的瓶頸;

電磁波

  • 電磁波的功能特性,是由它的頻率決定的。不同頻率的電磁波,有不同的屬性特點,從而有不同的用途。例如,高頻的γ射線,具有很大的殺傷力,可以用來治療腫瘤。
  • 電波和光波,都屬于電磁波,目前主要使用電波進行通信。當然,光波通信也在崛起,例如LiFi;電波的頻率資源是有限的,為了避免干擾和沖突,我們在電波這條公路上進一步劃分車道,分配給不同的對象和用途。目前全球主流的4G LTE技術標準,屬于特高頻和超高頻。

無線通信的頻率

  • 先說一個公式:c=λv, 即 光速=波長×頻率,無論是1G、2G、3G,還是4G、5G,萬變不離其宗,全部都是在它身上做文章;
  • 隨著1G、2G、3G、4G的發展,使用的電波頻率是越來越高的,主要是因為,頻率越高,能使用的頻率資源越豐富。頻率資源越豐富,能實現的傳輸速率就越高。(頻率資源就像車廂,越高的頻率,車廂越多,相同時間內能裝載的信息就越多。)
  • 既然,頻率高這么好,你一定會問:“為什么以前我們不用高頻率呢?”,原因很簡單,不是不想用,是用不起。電磁波的顯著特點就是頻率越高,波長越短,越趨近于直線傳播(繞射能力越差),在傳播介質中的衰減也越大,移動通信如果用了高頻段,那么它最大的問題,就是傳輸距離大幅縮短,覆蓋能力大幅減弱。相反的,頻率越低,網絡建設就越省錢,競爭起來就越有利。這就是為什么,這些年,電信、移動、聯通為了低頻段而爭得頭破血流。
  • 5G的一大技術特點就是 毫米波, 覆蓋同一個區域,需要的5G基站數量,將大大超過4G。

基站

  • 基站有兩種,微基站和宏基站。看名字就知道,微基站很小(城區和室內常見,5G時代更將隨處可見),宏基站很大(室外常見,建一個覆蓋一大片))
  • 那么多基站在身邊,會不會對人體造成影響?其實,和傳統認知恰好相反,事實上,基站數量越多,輻射反而越小!(基站小,功率低,對大家都好。如果只采用一個大基站,離得近,輻射大,離得遠,沒信號,反而不好。)(頻率:電波<過度頻帶<紅外線<可見光<紫外線<x射線<γ射線,可見電波的最高頻率仍小于可見光頻率)

天線去哪了

  • 以前大哥大都有很長的天線,早期的手機也有突出來的小天線,為什么現在我們的手機都沒有天線了,其實,我們并不是不需要天線,而是我們的天線變小了,根據天線特性,天線長度應與波長成正比,大約在1/10~1/4之間,手機的通信頻率越來越高,波長越來越短,天線也就跟著變短啦;

Massive MIMO(多天線技術)

  • MIMO就是“多進多出”(Multiple-Input Multiple-Output),多根天線發送,多根天線接收,在LTE時代,我們就已經有MIMO了,但是天線數量并不算多,只能說是初級版的MIMO,到了5G時代,繼續把MIMO技術發揚光大,現在變成了加強版的Massive MIMO(Massive:大規模的;5G是毫米波通信,天線也變成毫米級,手機里就可以集成很多根天線);

千兆級 LTE

  • 指的是蜂窩網絡在理論上速度可以達到光纖級別的 1Gbps(125MB/s)。雖然基于 4G 標準,但通過MIMO(多輸入多輸出)、使用載波聚合的LAA等技術,現在已經發展到千兆級 LTE。

Link Turbo

  • 手機廠商為了提升用戶的網絡體驗,也會做各種各樣的定制優化,華為推出的Link Turbo 網絡聚合加速技術就是其中比較硬核的一種“黑科技”。
  • 從硬件角度來說,WiFi 和蜂窩網絡屬于基帶芯片的不同模塊,我們可以簡單的把它們理解為類似雙網卡的情形。所謂的 Link Turbo 就是在使用 WiFi 的同時使用移動網絡加速。雙通道的技術以前也有,偵測到 WiFi 網絡不穩定時,自動切換到移動網絡,而 Link Turbo 硬核的地方在于可以同時使用兩條通道傳輸數據,而且支持 TCP 與 UDP。

網絡I/O

Socket 描述符(socket fd)

  • 一切皆文件”,Linux 內核會把所有外部設備都看作一個文件來操作。在網絡 I/O 中系統對一個 Socket 的讀寫也會有相應的描述符,稱為 socket fd;

同步

  • 同步就是一個任務的完成需要依賴另外一個任務時,只有等待被依賴的任務完成后,依賴的任務才能算完成,這是一種可靠的任務序列。要么成功都成功,失敗都失敗,兩個任務的狀態可以保持一致

異步

  • 異步是不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什么工作,依賴的任務也立即執行,只要自己完成了整個任務就算完成了。至于被依賴的任務最終是否真正完成,依賴它的任務無法確定,所以它是不可靠的任務序列。
  • 異步操作是可以被阻塞住的,只不過它不是在處理消息時阻塞,而是在等待消息通知時被阻塞

阻塞

  • 是指調用結果返回之前,當前線程會被掛起,一直處于等待消息通知,不能夠執行其他業務。函數只有在得到結果之后才會返回。

非阻塞

  • 非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。

小明的故事

  • 以小明下載文件為例
  1. 同步阻塞:小明一直盯著下載進度條,到 100% 的時候就完成。
  2. 同步非阻塞:小明提交下載任務后就去干別的,每過一段時間就去瞄一眼進度條,看到 100% 就完成。
  3. 異步阻塞:小明換了個有下載完成通知功能的軟件,下載完成就“叮”一聲。不過小明仍然一直等待“叮”的聲音
  4. 異步非阻塞:仍然是那個會“叮”一聲的下載軟件,小明提交下載任務后就去干別的,聽到“叮”的一聲就知道完成了

網絡I/O 模型

  • 《UNIX 網絡編程》中將 UNIX 網絡 I/O 模型分為以下五種(前四種均為同步):
1. 阻塞I/O
  • 阻塞I/O:用戶空間的應用程序執行一個系統調用,這會導致應用程序阻塞,什么也不干,直到數據準備好,并且將數據從內核復制到用戶進程,最后進程再處理數據,在等待數據到處理數據的兩個階段,整個進程都被阻塞。不能處理別的網絡IO。
2. 非阻塞I/O
  • 非阻塞I/O:非阻塞的recvform系統調用調用之后,進程并沒有被阻塞,內核馬上返回給進程,如果數據還沒準備好,此時會返回一個error。進程在返回之后,可以干點別的事情,然后再發起recvform系統調用。重復上面的過程,循環往復的進行recvform系統調用。這個過程通常被稱之為輪詢。輪詢檢查內核數據,直到數據準備好,再拷貝數據到進程,進行數據處理。
3. 多路復用I/O
  • 由于同步非阻塞方式需要不斷主動輪詢,輪詢占據了很大一部分過程,輪詢會消耗大量的CPU時間,而 “后臺” 可能有多個任務在同時進行,人們就想到了循環查詢多個任務的完成狀態,只要有任何一個任務完成,就去處理它。如果輪詢不是進程的用戶態,而是有人幫忙就好了。那么這就是所謂的 “IO 多路復用”。UNIX/Linux 下的 select、poll、epoll 就是干這個的(epoll 比 poll、select 效率高,做的事情是一樣的)。
4. 信號驅動式I/O
  • 首先我們允許Socket進行信號驅動IO,并安裝一個信號處理函數,進程繼續運行并不阻塞。當數據準備好時,進程會收到一個SIGIO信號,可以在信號處理函數中調用I/O操作函數處理數據。
5. 異步I/O
  • 相對于同步IO,異步IO不是順序執行。用戶進程進行aio_read系統調用之后,無論內核數據是否準備好,都會直接返回給用戶進程,然后用戶態進程可以去做別的事情。等到socket數據準備好了,內核直接復制數據給進程,然后從內核向進程發送通知。IO兩個階段,進程都是非阻塞的。

網絡性能評估與優化

性能評估

延遲與帶寬

  • 延遲:數據從信息源發送到目的地所需的時間。
  • 帶寬:邏輯或物理通信路徑最大的吞吐量。
  • 延遲和帶寬涉及的因素也非常多,例如信號的強度、附近有沒有基站、距離有多遠等;還跟使用的網絡制式,正在使用 3G、4G 還是 5G 網絡有關,并且網絡的擁塞情況也會產生影響
  • 不同的應用對延遲和帶寬的側重點可能不太一樣。對于直播類應用或者“王者榮耀”來說,延遲會更重要一些;對騰訊視頻、愛奇藝這種點播的應用來說,帶寬會更加重要一些。
不同網絡制式的帶寬與延遲參考值
網絡制式       帶寬(下行/上行)      延遲
2.75 G     384KB/48KB         600~700ms
3 G            7MB/2MB                150~400ms
4 G            128MB/56MB         40~50ms
5G         >100MB/>50MB       <10ms

弱網絡

  • 高延遲、低帶寬的網絡場景也就是我們常說的“弱網絡”
特點:
  1. 丟包率高:信號問題,用戶過多,誤碼包,用戶移動,基站切換
  2. 誤碼率高:環境電波,用戶距離遠
  3. 不穩定的延遲:用戶數量,信令分配,丟包,誤碼包
  4. 不穩定的帶寬:基站距離,用戶數量,擁塞控制

性能測量

  • 吞吐量:網絡接口接收和傳輸的每秒字節數。
  • 延遲:系統調用發送 / 接收延時、連接延遲、首包延遲、網絡往返時間等。
  • 連接數:每秒的連接數。
  • 錯誤:丟包計數、超時等。

網絡性能分析工具

  • strace: 跟蹤Socket相關的系統調用
  • netstat:多種網絡棧和接口統計信息
  • ifconfig:接口配置
  • ip:網絡接口統計信息
  • ping:測試網絡連通性
  • traceroute:測試網絡路由
  • tcpdump:網絡數據包嗅探器
  • 抓包工具Wireshark,Fiddler,Charles等:圖形化的網絡數據報檢查
  • 如果你對 Linux 底層更加熟悉,可以直接查看 /proc/net,它里面包含了許多網絡統計信息的文件。例如Android 的TrafficState接口就是利用 /proc/net/xt_qtaguid/stats 和 /proc/net/xt_qtaguid/iface_stat_fmt 文件來統計應用的流量信息。

TPC 優化

  • 因特網有兩個核心協議:IP 和 TCP,IP負責聯網主機之間的路由選擇和尋址;TCP負責在不可靠的傳輸信道之上提供可靠的抽象層。而 TCP/IP 也常被稱為 “因特網協議套件”(Internet Protocol Suite)。
1. 重用連接
  • 三次握手帶來的延遲使得每創建一個新 TCP 連接都要付出很大代價。而這也決定了提高 TCP 應用性能的關鍵,在于想辦法重用連接。
TFO(TCP Fast Open,TCP快速打開)
  • TFO 致力于減少新建 TCP 連接帶來的性能損失。但卻只能在某些情況下有效。比如,隨同 SYN 分組一起發送的數據凈荷有最大尺寸限制、只能發送某些類型的 HTTP 請 求,以及由于依賴加密 cookie,只能應用于重復的連接。
2. 擁塞預防及控制
流量控制
  • (滑動窗口)為實現流量控制,TCP 連接的每一方都要通告自己的接收窗口(rwnd),其中包含能夠保存數據的緩沖區空間大小信息。這個過程貫穿于每個 TCP 連接的整個生命周期: 每個 ACK 分組都會攜帶相應的最新 rwnd 值,以便兩端動態調整數據流速,使之適應發送端和接收端的容量及處理能力。
慢啟動
  • 由小到大逐漸增加發送數據量;每收到一個報文確認,就加一;超過慢啟動閾值(ssthresh) 則不再增長。
擁塞預防
  • 擁塞預防算法把丟包作為網絡擁塞的標志,即路徑中某個連接或路由器已經擁堵了,以至于必須采取刪包措施。因此,必須調整窗口大小,以避免造成更多的包丟失, 從而保證網絡暢通
TCP PRR(Proportional Rate Reduction,比例降速)
  • 最初,TCP 使用 AIMD(Multiplicative Decrease and Additive Increase,倍減加增) 算法,即發生丟包時,先將擁塞窗口減半,然后每次往返再緩慢地給窗口增加一 個固定的值。后來,出現了 PRR(Proportional Rate Reduction,比例降速),它是 RFC 6937 規定的一個新算法,其目標就是 改進丟包后的恢復速度。使用它因丟包造成的平均連接延遲減少了 3%~10%。此外,PRR 現在也是 Linux 3.2+ 內核默認的擁塞預防算法。
客戶端優化
  1. 少發或者不發網絡情況(請求合并):消除不必要的數據傳輸本身就是很大的優化。比如,減少下載不必要的資源,或者通過壓縮算法把要發送的比特數降到最低。
  2. 使用 CDN,讓通信距離更短:通過在不同的地區部署服務器,把數據放到接近客戶端的地方,可以減少網絡往返的延遲,從而顯著提升 TCP 性能。
  3. 重用 TCP 連接:把慢啟動和其他擁塞控制機制的影響降到最低。

UDP 優化

  • UDP 的特色在于它所省略的那些功能:連接狀態、握手、重發、重組、重排、擁塞控制、擁塞預防、流量控制,甚至可選的錯誤檢測,統統沒有。
在 RFC 5405 中,對設計單播 UDP 應用程序給出了很多設計建議(WebRTC 協議是下述規則的設計典范),如下所示:
1. 必須容忍各種因特網路徑條件;
2. 應該控制傳輸速度;
3. 應該對所有流量進行擁塞控制;
4. 應該使用與 TCP 相近的帶寬;
5. 應該準備基于丟包的重發計數器;
6. 應該不發送大于路徑 MTU 的數據報;
7. 應該處理數據報丟失、重復和重排;
8. 應該足夠穩定以支持 2 分鐘以上的交付延遲;
9. 應該支持 IPv4 UDP 校驗和,必須支持 IPv6 校驗和;
10. 可以在需要時使用 keep-alive(最小間隔 15 秒)。

TLS(Transport Layer Security,傳輸層安全)

  • IETF 在標準化 SSL 協議時,將其改名為 Transport Layer Security (TLS,傳輸層安全)。很多人會混用 TLS 和 SSL,但嚴格來講它們并不相 同,因為它們指代的協議版本不同。
  • TLS 也可以實現在 UDP 之上,DTLS(Datagram Transport Layer Security,數據報傳輸層安全)(RFC 6347)就旨在以 TLS 協議為基礎,同時兼顧數據報交付模式并提供類似的安全保障。
TLS 協議的目標是為在它之上運行的應用提供三個基本服務:
  1. 加密:混淆數據的機制。
  2. 身份驗證:驗證身份標識有效性的機制。
  3. 數據完整性:檢測消息是否被篡改或偽造的機制。
TLS 優化
  1. 盡早完成握手
  2. 使用會話緩存與無狀態恢復
  3. TLS 記錄大小(小記錄會造成浪費,大記錄會導致延遲)
  4. 證書鏈的長度:如果證書鏈長度超過了 TCP 的初始擁塞窗口,那我們無意間就會讓握手多了一次往返:證書長度超過擁塞窗口,從而導致服務器停下來等待 客戶端的 ACK 消息。(解決方法:增大擁塞窗口,減少證書大小)
  5. OCSP 封套:服務器可以在證書鏈中包含(封套)證書頒發機構的 OCSP 響應,讓瀏覽器跳過在線查詢。把查詢 OCSP 操作轉移到服務器可以讓服務器緩存簽名的 OCSP 響應,從而節省很多客戶端的請求。
  6. HTTP 嚴格傳輸安全:一種安全策略機制,讓服務器通過簡單的 HTTP 首部(如 Strict-Transport-Security: max-age=31536000) 對適用的瀏覽器聲明訪問規則。

移動端優化

何為網絡庫

  • 實際開發中,我們很少會直接操作底層的網絡接口,而是使用網絡庫;
網絡庫的核心作用
  1. 統一編程接口:簡單易用,便于統一進行策略管理,流解析(JSON,XNML等)
  2. 全局網絡控制:統一的網絡調度,流量監控,容災管理(跳維護頁),控制日志輸出,增加攔截器等
  3. 高性能:
網絡庫對比
xUtils:
  • 這個框架非常全面,可以進行網絡請求,可以進行圖片加載處理,可以數據儲存,還可以對view進行注解,使用這個框架非常方便,但是缺點也是非常明顯的,使用這個項目,會導致項目對這個框架依賴非常的嚴重,一旦這個框架出現問題,那么對項目來說影響非常大的。
Volley:
  • Volley是Google官方出的一套小而巧的異步請求庫,該框架封裝的擴展性很強,支持HttpClient、HttpUrlConnection,甚至支持OkHttp,而且Volley里面也封裝了ImageLoader,所以如果你愿意你甚至不需要使用圖片加載框架,不過這塊功能沒有一些專門的圖片加載框架強大,對于簡單的需求可以使用,稍復雜點的需求還是需要用到專門的圖片加載框架。Volley也有缺陷,比如不支持post大數據,所以不適合上傳文件。不過Volley設計的初衷本身也就是為頻繁的、數據量小的網絡請求而生。
  • 優勢在于封裝的更好
Retrofit:
  • Retrofit是Square公司出品的默認基于OkHttp封裝的一套RESTful網絡請求框架。Retrofit的封裝可以說是很強大, 里面涉及到一堆的設計模式,可以通過注解直接配置請求,可以使用不同的http客戶端,雖然默認是用http ,可以使用不同Json Converter 來序列化數據,同時提供對RxJava的支持,使用Retrofit + OkHttp + RxJava + Dagger2可以說是目前比較潮的一套框架,但是需要有比較高的門檻。
  • Retrofit解耦的更徹底
  • 默認使用OkHttp,性能上也要比Volley占優勢
okHttp:
  • okHttp針對Java和Android程序,封裝的一個高性能的http請求庫,支持同步,異步,而且封裝了線程池,封裝了數據轉換, 封裝了參數的使用,錯誤處理等。API使用起來更加的方便。但是我們在項目中使用的時候仍然需要自己在做一層封裝,這樣才能使用的更加的順手。
  • OkHttp的優勢在于性能更高
  • DNS管理:支持DNS緩存,支持對接自己的HTTPDNS
  • 并發模型:使用多線程實現并發,實際執行線程數受隊列機制控制,最大64,單個Host限制5個;
  • 連接管理:對于http連接,每個域名最多緩存5個連接,默認KeepTime是5分鐘,對于HTTP/2連接,每個域名都共用一個H/2連接;
  • IO模型:阻塞Socket,使用OKio包裝Socket進行流讀寫;
  • 網絡質量監控:默認不支持,有一些第三方插件;
  • 長連接:默認不支持;
  • 跨平臺:java實現,無法跨平臺;
  • 二次開發:容易;
  • 協議支持:HTTP/1.1,HTTP/2.0,TLS1.1,TLS1.2
Chromium 的Cronet:
  • 蘑菇街、頭條、UC 瀏覽器都在 Chromium 網絡庫上做了二次開發;
  • DNS管理:支持DNS緩存,支持對接自己的HTTPDNS;
  • 并發模型:每個host對應一條線程,每個線程可以創建6個非阻塞socket請求網絡;
  • 連接管理:對于HTTP連接每個域名最多緩存6個連接,對于HTTP/2連接,每個域名都共用一個H/2連接;
  • IO模型:epll+非阻塞socket;
  • 網絡質量監控:Predictor用于收集使用數據并預測網絡行為,NQE提供當前網絡質量評估;
  • 長連接:默認不支持;
  • 跨平臺:c++實現,可以跨平臺;
  • 二次開發:實現復雜,不容易擴展;
  • 協議支持:HTTP/1.1,HTTP/2.0,QUIC,TLS1.1,TLS1.2,TLS1.3
微信 Mars:
  • 在弱網絡方面做了大量優化,拼多多、虎牙、鏈家、美麗說這些應用都在使用 Mars;
  • DNS管理:支持DNS緩存,支持對接自己的HTTPDNS;
  • 并發模型:每個短連都是一個線程,沒有線程限制;
  • 連接管理:支持復合連接,沒有連接管理;
  • IO模型:epll+非阻塞socket;
  • 網絡質量監控:SDT模塊支持網絡偵測與診斷;
  • 長連接:默認支持;
  • 跨平臺:c++實現,可以跨平臺;
  • 二次開發:相比Cronet簡單一些;
  • 協議支持:信令網絡,只支持TCP;
  • 查看更多:https://github.com/Tencent/mars/wiki
大網絡平臺
  • 阿里的ACCS、螞蟻的mPaaS、攜程的網絡服務都是公司級的網絡中臺服務,這樣所有的網絡優化可以讓整個集團的所有接入應用受益。

為何優化

  • 等待網絡是我們 App 最大的性能瓶頸,直接影響到用戶體驗,用戶粘性,用戶忠誠度,以及轉化率;

何為優化

  • 一個數據包從手機出發要經過無線網絡、核心網絡以及外部網絡(互聯網),才能到達我們的服務器;
    (手機 => 無線網絡 => 基站 => 運營商核心網 => 互聯網 => 服務器)
影響網絡請求速度的因素:
  1. 客戶端網絡庫的內部設計和策略:IO并發模型,針對網絡問題的優化
  2. 服務器性能:并發能力,帶寬能力
  3. 網絡相關:用戶網絡(弱網,強網),運營商,網絡鏈路
網絡優化的核心:
  • 速度,弱網絡,安全,其他的還有造成的耗電,流量問題;
網絡請求步驟:
  1. DNS解析:通過DNS服務器拿到對應域名的IP,需要關注 DNS解析耗時,運營商LocalDns劫持,DNS調度等;
  2. 創建連接:與服務器建連接,包括TCP三次握手,TLS密鑰協商等,需要關注 多個IP/端口如何選擇,是否使用HTTPS,能否減少創建連接的時間;
  3. 發送/接受數據:數據的組裝,發送,接收,解析,需要關注 根據網絡狀況利用帶寬,偵測網絡延時,弱網下調整包大小;
  4. 關閉連接:需要關注 主動關閉和被動關閉兩種情況;

HTTPDNS

  • DNS解析是網絡請求的第一步,默認使用運營商的LocalDNS服務;
LocalDNS存在的問題:
  1. 解析慢,4G約100ms,3G約200~300ms
  2. 穩定性:UDP協議,無狀態,容易域名劫持(難復現,難定位,難解決)
  3. 準確性:調度經常不準確,跨地域,跨運營商調度會導致訪問慢,甚至訪問不了
  4. 及時性:運營商可能修改DNS的TTL,導致DNS修改生效延遲
  • 為了解決上述問題就有了HTTPDNS,即自己做域名解析,通過http請求后臺去拿到域名對應的IP地址,大網絡平臺會有統一的HTTPDNS服務,并和運維系統打通,還會增加精準的流量調度,網絡撥測/灰度,網絡容災等;

連接復用

  • 前面對比網絡庫中講的連接管理,網絡庫不會吧連接立刻釋放,而是放到連接池中,如果有另一個請求的域名和端口是一樣的,就可以復用,減少建立連接耗時(TCP三次握手,TLS密鑰協商等);
  • 原理:利用HTTP協議里的keep-alive,或HTTP/2.0的多路復用(多條請求在這條連接上并發進行)
  • 問題:常用的OkHttp對應HTTP/2.0的連接,同一個域名只會保留一條連接,網絡擁塞的時候容易出現TCP隊首擁塞問題,這種情況可以通過修改網絡庫或者禁用HTTP/2.0解決;

壓縮與加密

  • 講完連接,再來看看發送和接收的優化,第一重要的就是減少傳輸的數據量,也就是數據壓縮;
對于HTTP請求數據主要有三部分:
  1. 請求header:HTTP/2.0本身有頭部壓縮技術
  2. 請求URL:一般我們會有很多公共參數,這些參數大部分是不變的,可以只上傳一次,在統一接入層進行參數擴展
  3. 請求body:一是通信協議的選擇,在網絡傳輸中目前最流行的兩種數據序列化方式是 JSON 和 Protocol Buffers,Protocol Buffers 使用起來更加復雜一些,但在數據壓縮率、序列化與反序列化速度上面都有很大的優勢。二是壓縮算法的選擇,通用的壓縮算法主要是如 gzip,Google 的Brotli或者 Facebook 的Z-standard都是壓縮率更高的算法。
  • 針對特定數據我們還有其他的壓縮方法,例如針對圖片我們可以使用 webp、hevc、SharpP等壓縮率更高的格式。另外一方面,基于 AI 的圖片超清化也是一大神器,QQ 空間通過這個技術節約了大量的帶寬成本。

安全

  • 數據安全也是網絡重中之重的一個環節,在大網絡平臺中是基于 HTTPS 的 HTTP/2 通道,已經有了 TLS 加密。
  • 但是 HTTPS 帶來的代價也是不小的,它需要 2-RTT 的協商成本,在弱網絡下時延不可接受。同時后臺服務解密的成本也十分高昂,在大型企業中需要單獨的集群來做這個事情。

HTTPS 的優化

  1. 連接復用率:多個域名共用同一個 HTTP/2 連接、長連接等方式
  2. 減少握手次數:TLS 1.3可以實現 0-RTT 協商,事實上在 TLS 1.3 release 之前,微信的mmtls、Facebook 的fizz、阿里的 SlightSSL 都已在企業內部大規模部署。
  3. 性能提升:使用 ecc 證書代替 RSA,服務端簽名的性能可以提升 4~10 倍,但是客戶端校驗性能降低了約 20 倍,從 10 微秒級降低到 100 微秒級。另外一方面可以通過 Session Ticket 會話復用,節省一個 RTT 耗時。
  4. 其他優化:一些方案可能是需要用錢堆出來的,比如部署跨國的專線、加速點,多 IDC 就近接入等。除此之外,使用CDN 服務、P2P 技術也是比較常用的手段,特別在直播這類場景。
    1. 異地多活:多個地區同時存在對等的多個機房,以用戶維度劃分,多機房共同承擔全量用戶的流量。
    2. 抗抖動優化:應用一種有策略的重試機制,將網絡請求以是否發送到 socket 緩沖區作為分割
    3. SYNC 機制:同步差量數據,達到節省流量,提高通信效率與請求成功率。客戶端用戶不在線時,SYNC 服務端將差量數據保持在數據庫中。當客戶端下次連接到服務器時,再同步差量數據給用戶。
    4. 高并發流量處理:服務端接入層多級限流,
    5. JobScheduler:結合 JobScheduler 來根據實際情況做網絡請求. 比方說 Splash 閃屏廣告圖片, 我們可以在連接到 Wifi 時下載緩存到本地; 新聞類的 App 可以在充電, Wifi 狀態下做離線緩存。
    6. 網絡請求優先級排序:app應該對網絡請求劃分優先級盡可能快地展示最有用的信息給用戶。(高優先級的服務優先使用長連接)
    7. 建立長連通道:將眾多請求放入等待發送隊列中,待長連通道建立完畢后再將等待隊列中的請求放在長連通道上依次送出。
    8. 減少域名和避免重定向
    9. 沒有請求的請求,才是最快的請求。

移動端監控

  • 不論是基站故障、光纖被挖斷、運營商挾持,還是我們的機房、CDN 服務商出現故障,都有可能會引起用戶網絡出現問題。
  • 即使我們使用了OkHttp網絡庫,也可能會有一些開發人員或者第三方組件使用了系統的網絡庫。那應該如何統一的監控客戶端的所有的網絡請求呢?
1. 插樁:
  • 360 開源的性能監控工具ArgusAPM就是利用 Aspect 切換插樁,實現監控系統和 OkHttp 網絡庫的請求。(參考其TraceNetTrafficMonitor,OkHttp3Aspect)
  • 插樁的方法看起來很好,但是并不全面。如果使用的不是系統和 OkHttp 網絡庫,又或者使用了 Native 代碼的網絡請求,都無法監控到。
2. Native Hook:
3. 統一網絡庫
  • 盡管拿到了所有的網絡調用,想想會有哪些使用場景呢?模擬網絡數據、統計應用流量,或者是單獨代理 WebView 的網絡請求。

如何監控流量

  • 應用流量監控的方法非常簡單,一般通過 TrafficStats 類。TrafficState 是 Android API 8 加入的接口,用于獲取整個手機或者某個 UID 從開機算起的網絡流量。至于如何使用可以參考https://github.com/facebook/network-connection-class
getMobileRxBytes()        //從開機開始Mobile網絡接收的字節總數,不包括Wifi
getTotalRxBytes()         //從開機開始所有網絡接收的字節總數,包括Wifi
getMobileTxBytes()        //從開機開始Mobile網絡發送的字節總數,不包括Wifi
getTotalTxBytes()         //從開機開始所有網絡發送的字節總數,包括Wifi
//原理:讀取 proc,并將目標 UID 下面所有網絡接口的流量相加。
//Android 7.0 之后只能通過 TrafficStats 拿到自己應用的流量信息
網絡測試模式:
  • Android 手機跟 iPhone 都有一個網絡測試模式
  • iPhone:打開撥號界面,輸入“3001#12345#”,然后按撥號鍵。
  • Android 手機:打開撥號界面,輸入“##4636##”,然后按撥號鍵(可進入工程測試模式,部分版本可能不支持)。

參考

我是今陽,如果想要進階和了解更多的干貨,歡迎關注微信公眾號 “今陽說” 接收我的最新文章

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一、背景 一般情況下,我們都是用一些封裝好的網絡框架去請求網絡,對底層實現不甚關注,而大部分情況下也不需要特別關注...
    vivo互聯網技術閱讀 426評論 0 0
  • 題記 最近在極客時間上面學習了劉超老師的《趣談網絡協議》,深入淺出的介紹了網絡協議的原理和應用,受益匪淺。這里把文...
    追那個小女孩閱讀 1,155評論 0 13
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,588評論 28 53
  • 人工智能是什么?什么是人工智能?人工智能是未來發展的必然趨勢嗎?以后人工智能技術真的能達到電影里機器人的智能水平嗎...
    ZLLZ閱讀 3,846評論 0 5
  • 首先介紹下自己的背景: 我11年左右入市到現在,也差不多有4年時間,看過一些關于股票投資的書籍,對于巴菲特等股神的...
    瞎投資閱讀 5,768評論 3 8