深入探索 Android 網絡優化(二、網絡優化基礎篇)上

前言

成爲一名優秀的Android開發,需要一份完備的知識體系,在這裏,讓我們一起成長爲自己所想的那樣~。

思維導圖大綱

一、爲什麼要進行網絡優化?

「等待網絡是我們 App 最大的性能瓶頸,再怎麼優化繪製、內存、卡頓或其它方面,也抵不上網絡優化」!網絡通信速度越快,則:

  • 1)、「用戶黏性越高」

  • 2)、「用戶忠誠度更高」

  • 3)、「轉化率越高」

而網絡優化最核心的處理方式就是 「消除和減少不必要的網絡延遲,把傳輸的字節數降到最少」

二、網絡性能評估

1、無線網絡通信過程

手機 => 無線網絡 => 基站 => 運營商核心網 => 互聯網 => 服務器
複製代碼

2、重要指標

1)、延時

「數據從信息源發送到目的地所需的時間」。客戶端到服務端的總延遲時間如下所示:

  • 1)、「傳播延遲:消息從發送端到接收端需要的時間,是信號傳播距離和速度的函數。光速是所有能量、物質和信息運動所能達到的最高速度,這個結論給網絡分組的傳播速度設定了上限」

  • 2)、「傳輸延遲:把消息中的所有比特轉移到鏈路中需要的時間,是消息長度和鏈路速率的函數」

  • 3)、「處理延遲:處理分組首部、檢查位錯誤及確定分組目標所需的時間」

  • 4)、「排隊延遲:到來的分組排隊等待處理的時間」

一路上經過的路由器越多,每個分組的處理和傳輸延遲就越多。並且,網絡流量越擁擠,分組在入站緩衝區中被延遲的可能性就越大。

最後,延遲中相當大的一部分往往花在了最後幾公里,通過 traceroute 命令,我們就可以知道上網服務商的拓撲結構和速度。

2)、帶寬

「邏輯或物理通通信路徑的最大吞吐量」

網絡核心的帶寬

光纖

就是一根“光導管”,比人的頭髮稍粗一點,專門用來從一端向另一端傳送光信號。

金屬線

用於傳送電信號,但信號損失、電磁干擾較大,同時維護成本也較高。

這兩種線路我們的數據分組很可能都會經過,但一般長距離的分組傳輸都是通過光纖完成的。

通過 「波分複用(WDM,Wavelength-Division Multiplexing)技術,光纖可以同時傳輸很多不同波長(信道)的光」,因而具有明顯的帶寬優勢。

「一條光纖連接的總帶寬,等於每個信道的數據傳輸速率乘以可複用的信道數。而每條光纜會封裝幾條光纖(常見的是4條),折算出來的帶寬容量能達到每秒幾百太比特」

網絡邊緣的帶寬

用戶可用帶寬取決於客戶端與目標服務器間最低容量連接,我們可以在 akamai 查看世界各地的平均帶寬。但是,「高帶寬並不能保證端到端的傳輸速度」

延遲、帶寬與什麼因素有關?

「信號強度、基站距離、網絡制式、擁塞情況」 等等很多因素相關。

3、瞭解不同網絡制式的帶寬與延遲參考值

網絡制式帶寬(下行/上行)延遲
2.75 G384KB/48KB600~700ms
3 G7MB/2MB150~400ms
4 G128MB/56MB40~50ms
5G>100MB/>50MB<10ms

什麼是弱網絡?

「高延時、低帶寬」 的網絡,它具有 「丟包率、誤碼率高」 的特點。

「網絡優化需要結合 App 的實際情況來綜合考慮,看我們的 App 是重延時的應用還是重帶寬的應用」

遺憾的是,人類不太可能跳出物理定律的 “掌心”。如果需要針對延遲採取優化措施,就必須從 「設計和優化協議及應用」 着手,並且時刻牢記光速的限制。

三、TPC 優化

因特網有兩個核心協議:IP 和 TCP。

  • IP:即 Internet Protocol(因特網協議),負責聯網主機之間的路由選擇和尋址;

  • TCP:即 Transmission Control Protocol(傳輸控制協議),負責在不可靠的傳輸信道之上提供可靠的抽象層。

而 TCP/IP 也常被稱爲“因特網協議套件”(Internet Protocol Suite)。在現實當中,由於 TCP 提 供了很多有用的功能,幾乎所有 HTTP 流量都是通過 TCP 傳送的。

我們都知道有 IPv4 和 IPv6,那 IPv1~3 和 IPv5 呢?

IPv4 中的 4 表示 TCP/IP 協議的第 4 個版本,發佈於 1981 年 9 月。「IPv4 中的 v4 只是表明了它與 TCP 前 3 個版本的承繼關係,之前並沒有單獨的 IPv1、IPv2 或 IPv3 協議。而 v5 已經被分配給了另一個試驗性協議 Internet Stream Protocol(ST)」。但 ST 一直沒有什麼進展,這也是我們爲什麼很少聽說它的原因。結果 TCP/IP 的下 一版本就成了 IPv6。

1、三次握手

  • 1)、出於安全考慮,序列號由兩端隨機生成。

  • 2)、客戶端可以在發送 ACK 分組之後立即發送數據,而服務器必須等接收到 ACK 分組之後才能發送數據。

  • 3)、三次握手帶來的延遲使得每創建一個新 TCP 連接都要付出很大代價。而這也決定了提高 TCP 應用性能的關鍵,在於想辦法重用連接。

TFO(TCP Fast Open,TCP 快速打 開)

TFO 致力於減少新建 TCP 連接帶來的性能損失。但卻只能在某些情況下有效。比如,「隨同 SYN 分組一起發送的數據淨荷有最大尺寸限制、只能發送某些類型的 HTTP 請 求,以及由於依賴加密 cookie,只能應用於重複的連接」

2、擁塞預防及控制

ARPANET(Advanced Research Projects Agency Network,高級研究計劃局 網絡) 是現代互聯網的前身,是世界上第一個實際運行的分組交換網絡。這個項目於 1959 年正式啓動,「1983 年 TCP/IP 作爲主要通信協議取代了原來 的 NCP(Network Control Program)協議」

1)、流量控制

爲實現流量控制,TCP 連接的每一方都要通告自己的接收窗口(rwnd),其中包含能夠保存數據的緩衝區空間大小信息。這個過程貫穿於每個 TCP 連接的整個生命週期: 「每個 ACK 分組都會攜帶相應的最新 rwnd 值,以便兩端動態調整數據流速,使之適應發送端和接收端的容量及處理能力」

窗口縮放(RFC 1323)

最初的 TCP 規範分配給通告窗口大小的字段是 16 位的,RFC 1323 提供了“TCP 窗口縮放”(TCP Window Scaling)選項,可以 「把接收窗口大小由 65535 字節提高到 1G 字節」!縮放 TCP 窗口是在三次握手期間完成的,其中有一個值表示在將來的 ACK 中左移 16 位窗口字段的位數。

2)、慢啓動

擁塞窗口大小(cwnd),即發送端對從客戶端接收確認(ACK)之前可以發送數據量的限制。

新 TCP 連接傳輸的最大數據量取 rwnd 和 cwnd 中的最小值,而服務器實際上可以 向客戶端發送 4 個 TCP 段,然後就必須停下來等待確認。

爲減少增長到擁塞窗口的時間,可以減少客戶端與服務器之間的往返時間。比如, 把服務器部署到地理上靠近客戶端的地方。要麼,就把初始擁塞窗口大小增加到 RFC 9828 規定的 10 段。

因爲慢啓動限制了可用的吞吐量,而這對於小文件傳輸非常不利。

SSR(Slow-Start Restart,慢啓動重啓)

在連接空閒一定時間後重置連接的擁塞窗口。道理很簡單, 在連接空閒的同時,網絡狀況也可能發生了變化,爲了避免擁塞,理應將擁塞窗口重置回“安全的”默認值。

但是,「SSR 對於那些會出現突發空閒的長週期 TCP 連接(比如 HTTP 的 keep-alive 連接)有很大的影響。因此,我們建議在服務器上禁用 SSR」

可以看到,服務器和客戶端之間的 5 Mbit/s 帶寬並不影響 TCP 連接的啓動階 段。此時,延遲和擁塞窗口大小纔是限制因素。

3)、擁塞預防

慢啓動以保守的窗口初始化連接,隨後的 每次往返都會成倍提高傳輸的數據量,直到超過接收端的流量控制窗口,即系統 配置的擁塞閾值(ssthresh)窗口,或者有分組丟失爲止,此時擁塞預防算法介入。

「擁塞預防算法把丟包作爲網絡擁塞的標誌」,即路徑中某個連接或路由器已經擁堵了, 以至於必須採取刪包措施。因此,必須調整窗口大小,以避免造成更多的包丟失, 從而保證網絡暢通。

重置擁塞窗口後,擁塞預防機制按照自己的算法來增大窗口以儘量避免丟包。某個 時刻,可能又會有包丟失,於是這個過程再從頭開始。如果你看到過 TCP 連接的吞 吐量跟蹤曲線,發現該曲線呈鋸齒狀,那現在就該明白爲什麼了。這是擁塞控制和 預防算法在調整擁塞窗口,進而消除網絡中的丟包問題。

TCP PRR(Proportional Rate Reduction,比例降速)

最初,TCP 使用 AIMD(Multiplicative Decrease and Additive Increase,倍減加增) 算法,即發生丟包時,「先將擁塞窗口減半,然後每次往返再緩慢地給窗口增加一 個固定的值」

後來,出現了 PRR(Proportional Rate Reduction,比例降速),它是 RFC 6937 規定的一個新算法,其目標就是 「改進丟包後的恢復速度。使用它因丟包造成的平均連接延遲減少了 3%~10%。此外,PRR 現在也是 Linux 3.2+ 內核默認的擁塞預防算法」

3、BDP(Bandwidth-delay product,帶寬延遲積)

接收窗口(rwnd)會隨每次 ACK 一起發送,而 擁塞窗口(cwnd)則由發送端根據擁塞控制和預防算法動態調整。

無論發送端發送的數據還是接收端接收的數據超過了未確認的最大數據量,都必須停 下來等待另一方 ACK 確認某些分組才能繼續。

而 BDP(Bandwidth-delay product,帶寬延遲積) 就是 「任意時刻處於在途未確認狀態的最大數據量」

BDP = 數據鏈路的容量 * 其端到端延遲
複製代碼

「在高速連接的客戶端與服務器之間,如果實際傳輸速度只有可用帶寬的幾分之一,那窗口大小很可能就是 罪魁禍首。要麼因爲某一飽和端通告的接收窗口很小,要麼因爲網絡擁堵和丟包導致擁塞窗口重置,更可能因爲流量增長過快導致對連接吞吐量施加了限制」

4、TCP 隊首(HOL,Head of Line)阻塞

TCP 在不可靠的信道上實現了可靠的網絡傳輸。基本的分組錯誤檢測與糾正、按 序交付、丟包重發,以及保證網絡最高效率的流量控制、擁塞控制和預防機制,讓 TCP 成爲大多數網絡應用中最常見的傳輸協議。

但是,其中的按序交付和可靠交付有時候並不必要,反而會導致額外的延遲,對性能造成負面影響。例如:每個 TCP 分組都會帶着一個唯一的序列號被髮出,而 所有分組必須按順序傳送到接收端。如果中途有一個分組沒能到達接收 端,那麼後續分組必須保存在接收端的 TCP 緩衝區,等待丟失的分組重發併到達接 收端。這一切都發生在 TCP 層,應用程序對 TCP 重發和緩衝區中排隊的分組一無所 知,必須等待分組全部到達才能訪問數據。在此之前,應用程序只能在通過套接字 讀數據時感覺到延遲交付。這種效應稱爲 TCP 的隊首(HOL,Head of Line)阻塞。

「隊首阻塞使得分組到達時間會存在無法預知的延遲變化,而這個時間變化通常被稱爲抖動」

因此,對於無需按序交付數據或能夠處理分組丟失的應用程序,以及對延遲或抖動要求很高的應用程序,最好選擇 UDP 等協議。

丟包的反作用力

丟包是讓 TCP 達到最佳性能的關鍵。被刪除的包恰恰是一種反饋機制, 能夠讓接收端和發送端各自調整速度,以避免網絡擁堵,同時保持延遲最短。

對與實時性比較強的音視頻應用來說,就算有個包丟了,音頻編解碼器只要在音頻中插入一個小小的間歇,就可以繼續 處理後來的包。只要間歇夠小,用戶就注意不到,而等待丟失的包則可能導致音 頻輸出產生無法預料的暫停。相對來說,後者的用戶體驗更糟糕。

5、TCP 優化 Tips

1)、TCP 中的關鍵細節

  • 1)、「TCP 三次握手增加了整整一次往返時間」;

  • 2)、「TCP 慢啓動將被應用到每個新連接」;

  • 3)、「TCP 流量及擁塞控制會影響所有連接的吞吐量」;

  • 4)、「TCP 的吞吐量由當前擁塞窗口大小控制」

大多數情況下,「TCP 的瓶頸都是延遲,而非帶寬」

2)、服務端配置優化

1)、增大TCP的初始擁塞窗口

加大起始擁塞窗口可以讓 TCP 在第一次往返就傳輸較多數據,而隨後的速度提 升也會很明顯。對於突發性的短暫連接,這也是特別關鍵的一個優化。

2)、慢啓動重啓

在連接空閒時禁用慢啓動可以改善瞬時發送數據的長 TCP 連接的性能。

3)、窗口縮放(RFC 1323)

啓用窗口縮放可以增大最大接收窗口大小,可以讓高延遲的連接達到更好吞 吐量。

4)、TCP快速打開

在某些條件下,允許在第一個 SYN 分組中發送應用程序數據。TFO(TCP Fast Open,TCP 快速打開)是一種新的優化選項,注意,TFO 需要客戶端和服務器共同支持。

3)、客戶端優化

  • 1)、「少發或者不髮網絡情況(請求合併):消除不必要的數據傳輸本身就是很大的優化。比如,減少下載不必要的資源,或者通過壓縮算法把要發送的比特數降到最低」

  • 2)、「使用 CDN,讓通信距離更短:通過在不同的地區部署服務器,把數據放到接近客戶端的地方,可以減少網絡往返的延遲,從而顯著提升 TCP 性能」

  • 3)、「重用 TCP 連接:把慢啓動和其他擁塞控制機制的影響降到最低」

四、UDP 優化

數據報,即一個完整、獨立的數據實體,攜帶着從源節點到目的地節點的足夠信息,對這些 節點間之前的數據交換和傳輸網絡沒有任何依賴。

1、數據包和分組的區別

數據報(datagram)和分組(packet)是兩個經常被人混用的詞,實際上它們還是 有區別的。「分組可以用來指代任何格式化的數據塊,而數據報則通常只用來描述那 些通過不可靠的服務傳輸的分組,既不保證送達,也不發送失敗通知」

IETF 和 W3C 工作組共同制定了一套新 API—— WebRTC(Web Real-Time Communication,Web 實時通信)「WebRTC 着眼於在瀏覽器中通過 UDP 實現原生的語音和視頻實時通信,以及其他形式的 P2P(Peer-to-Peer,端到端)通信」

2、無協議服務

衆所周知,IP 層的主要任務就是按照地址從源主機向目標主機發送數據報。而 「數據報」 則暗示着:「IP 層不保證消息可靠的交付,也不發送失敗通知,實際上是把底層網絡的不可靠性直接暴露給了上一層」。如果某個路由節點因爲網絡擁塞、負載過高或其他原因而刪除了 IP 分組,那麼在必要的情況下,IP 的上一層協議要負責檢測、恢復和重發數據。

UDP 數據報中的源端口和校驗和字段都是可選的。IP 分組的首部也有校驗和,應用程序可以忽略 UDP 校驗和。因此,「UDP 僅僅是在 IP 層之上通過嵌入應用程序的源端口和目標端口,提供了一個“應用程序多路複用”機制」

UDP 的無服務

  • 1)、「不保證消息交付:不確認,不重傳,無超時」

  • 2)、「不保證交付順序:不設置包序號,不重排,不會發生隊首阻塞」

  • 3)、「不跟蹤連接狀態:不必建立連接或重啓狀態機」

  • 4)、「不需要擁塞控制:不內置客戶端或網絡反饋機制」

3、UDP 與網絡地址轉換器(NAT,Network Address Translator)

1)、連接狀態超時

對於較長時間的 UDP 通信,有一個事實上的最佳做法,即引入一個雙向 keep-alive 分組,「週期性地重置傳輸路徑上所有 NAT 設備中轉換記錄的計時器」

2)、NAT 穿透

NAT 導致了幾個問題,如下所示:

  • 1)、內部客戶端不知道外網 IP 地址,只知道內網 IP 地址。

  • 2)、任何到達 NAT 設備外網 IP 的分組還必須有一個目標端口,而且 NAT 轉換表中也要有一個條目可以將其轉換爲內部主機的 IP 地址和端口號。如果沒有這個條目(通常是從外網傳數據進來),那到達的分組就會被刪除。

爲解決 UDP 與 NAT 的這種不搭配,人們發明了很多穿透技術(TURN、STUN、 ICE),用於在 UDP 主機之間建立端到端的連接。

3)、STUN(Session Traversal Utilities for NAT)協議(RFC 5389)

優勢

  • 1)、應用程序可以獲得外網 IP 和端口,並利用這些信息與對端通信;

  • 2)、發送到 STUN 服務器的出站綁定請求將在通信要經過的 NAT 中建立路由條目, 使得到達該 IP 和端口的入站分組可以找到內網中的應用程序;

  • 3)、STUN 協議定義了一個簡單 keep-alive 探測機制,可以保證 NAT 路由條目不超時。

缺點

STUN 並不能適應所有類型的 NAT 和網絡配置。不僅如此,某些情況下 UDP 還會被防火牆或其他網絡設備完全屏蔽。

爲解決這個問題,在 STUN 失敗的情況下,我們還可以使用 TURN(Traversal Using Relays around NAT)協議(RFC 5766)作爲後備。TURN 可以在最壞的情況下跳過 UDP 而切換到 TCP。

4)、TURN(Traversal Using Relays around NAT)協議(RFC 5766)

工作流程

  • 1)、兩端都要向同一臺 TURN 服務器發送分配請求來建立連接,然後再進行權限協商。

  • 2)、協商完畢,兩端都把數據發送到 TURN 服務器,再由 TURN 服務器轉發,從而 實現通信。

缺點

爲滿足傳輸數據的需要,中繼設備的容量必須足夠大。

谷歌的 libjingle 是一個用 C++ 開發的用於構建端到端應用程序的開源庫,其文檔也爲我們考量現實中的 STUN 與 TURN 性能提供了有價值的參考:

  • 92% 的時間可以直接連接(STUN);

  • 8% 的時間要使用中繼器(TURN)。

5)、ICE(Interactive Connectivity Establishment)協議(RFC 5245)

ICE 規定了一套方法,致力於在通信各端之間建立一條最有效的通道:能直連就直連,必要時 STUN 協商,再不行使用 TURN。如下圖所示:

如果要構建基於 UDP 的 P2P 應用程序,我們應該選擇現有的平臺 API,或者實現了 ICE、STUN 和 TURN 的第三方庫。

4、UDP 優化 Tips

「UDP 的特色在於它所省略的那些功能:連接狀態、握手、重發、重組、重排、擁塞控制、擁塞預防、流量控制,甚至可選的錯誤檢測,統統沒有」

在 RFC 5405 中,對設計單播 UDP 應用程序給出了很多設計建議,如下所示:

  • 1)、「必須容忍各種因特網路徑條件」;

  • 2)、「應該控制傳輸速度」;

  • 3)、「應該對所有流量進行擁塞控制」;

  • 4)、「應該使用與 TCP 相近的帶寬」;

  • 5)、「應該準備基於丟包的重發計數器」;

  • 6)、「應該不發送大於路徑 MTU 的數據報」;

  • 7)、「應該處理數據報丟失、重複和重排」;

  • 8)、「應該足夠穩定以支持 2 分鐘以上的交付延遲」;

  • 9)、「應該支持 IPv4 UDP 校驗和,必須支持 IPv6 校驗和」;

  • 10)、「可以在需要時使用 keep-alive(最小間隔 15 秒)」

而 WebRTC 協議則是上述的設計典範。

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

SSL 協議在直接位於 TCP 上一層的應用層被實現。

IETF 後來在標準化 SSL 協議時,將其改名爲 Transport Layer Security (TLS,傳輸層安全)。很多人會混用 TLS 和 SSL,但嚴格來講它們並不相 同,因爲它們指代的協議版本不同。

鑑於 SSL 協議是網景公司專有的,IETF 成立了一個小組負責標準化該協 議,後來就有了 RFC 2246,即 TLS 1.0,也就是 SSL 3.0 的升級版。

  • 「TLS 1.0 在 1999 年 1 月發佈」

  • 「2006 年 4 月發佈了 TLS 1.1」

  • 「2008 年 8 月發佈了 TLS 1.2」

TLS 也可以實現在 UDP 之上,DTLS(Datagram Transport Layer Security,數據報傳輸層安全)(RFC 6347)就旨在以 TLS 協議爲基礎,同時兼顧數據報交付模式並提供類似的安全保障。

1、加密、身份驗證與完整性

TLS 協議的目標是爲在它之上運行的應用提供三個基本服務:

  • 1)、「加密:混淆數據的機制」

  • 2)、「身份驗證:驗證身份標識有效性的機制」

  • 3)、「數據完整性:檢測消息是否被篡改或僞造的機制」

1)、加密

在握手機制中設計最巧妙的地方,就是其使用的公鑰密碼系統 (也稱“非對稱密鑰加密”),這套系統可以讓通信雙方不必事先“認識”即可商定共 享的安全密鑰,而且協商過程還是通過非加密通道完成的。

2)、身份驗證

握手過程中,TLS 協議還允許通信兩端互相驗明正身。這個驗證首先需要建立“認證機構信任鏈”(Chain of Trust and Certificate Authorities)。

3)、數據完整性

消息分幀機制,使用 MAC (Message Authentication Code,消息認證碼)簽署每一條消息。MAC 算法是一個單向加密的散列函數(本質上是一個校驗和),「密鑰由連接雙方協商確定。只要發送 TLS 記錄,就會生成一個 MAC 值並附加到該消息中」。接收端通過計算和驗證這個 MAC 值來判斷消息的完整性和可靠性。

2、TLS 握手

  • 0 ms:TLS 在可靠的傳輸層(TCP)之上運行,這意味着首先必須完成 TCP 的“三 次握手”,即一次完整的往返。

  • 56 ms:TCP 連接建立之後,客戶端再以純文本形式發送一些規格說明,比如它所運 行的 TLS 協議的版本、它所支持的加密套件列表,以及它支持或希望使用的另外一 些 TLS 選項。

  • 84 ms:然後,服務器取得 TLS 協議版本以備將來通信使用,從客戶端提供的加密 套件列表中選擇一個,再附上自己的證書,將響應發送回客戶端。作爲可選項,服 務器也可以發送一個請求,要求客戶端提供證書以及其他 TLS 擴展參數。

  • 112 ms:假設兩端經過協商確定了共同的版本和加密套件,客戶端也高高興興地 把自己的證書提供給了服務器。然後,客戶端會生成一個新的對稱密鑰,用服務 器的公鑰來加密,加密後發送給服務器,告訴服務器可以開始加密通信了。到 目前爲止,除了用服務器公鑰加密的新對稱密鑰之外,所有數據都以明文形式 發送。

  • 140 ms:最後,服務器解密出客戶端發來的對稱密鑰,通過驗證消息的 MAC 檢 測消息完整性,再返回給客戶端一個加密的“Finished”消息。

  • 168 ms:客戶端用它之前生成的對稱密鑰解密這條消息,驗證 MAC,如果一切 順利,則建立信道並開始發送應用數據。

1)、應用層協議協商(ALPN,Application Layer Protocol Negotiation)

NPN(Next Protocol Negotiation,下一代協議協商)是谷歌在 SPDY 協議中開發的一個 TLS 擴展,「目的是通過在 TLS 握手期間協商應用協議來提高效率」

ALPN 是 IETF 在 NPN 基礎上修訂並批准的版本。在 NPN 中,服務器廣播自己 支持的協議,客戶端選擇和確認協議。而 「在 ALPN 中,交換次序顛倒過來了,客 戶端先聲明自己支持的協議,服務器選擇並確認協議。而這樣修改的目的是爲了讓 ALPN 與其他協議協商標準保持一致」

ALPN 作爲 TLS 擴展,讓我們能在 TLS 握手的同時協商應用協議,從而省掉了 HTTP 的 Upgrade 機制所需的額外往返時間。

只要 TLS 握手完成、建立了加密信道並就應用協議達成一致,客戶端與服務器就可 以立即通信。

2)、SNI (Server Name Indication,服務器名稱指示)

如果服務器想在一個 IP 地址爲多個站點提供服務,而每個站點都擁有自己的 TLS 證書,那怎麼辦?

爲了解決這個問題,SNI 擴展被引入 TLS 協議,該擴展 「允許客戶端在握手之初就指明要連接的主機名」

3、TLS 會話恢復

即在多個連接間共享協商後的安全密鑰。

1)、會話標識符 (Session Identifier,RFC 5246)

最早的“會話標識符”機制是在 SSL 2.0 中引入的, 支持服務器創建 32 字節的會話標識符,它是在完整的 TLS 協商期間作爲其“ServerHello”消息的一部分發送。

在內部,服務器會爲每個客戶端保存一個會話 ID 和協商後的會話參數。相應地,客 戶端也可以保存會話 ID 信息,並將該 ID 包含在後續會話的“ClientHello”消息中, 從而告訴服務器自己還記着上次握手協商後的加密套件和密鑰,這些都可以重用。

假設客戶端和服務器都可以在自己的緩存中找到共享的會話 ID 參數,那麼就可以進 行簡短握手。否則,就要重新啓動一次全新的會話協商,生成新的會話 ID。簡短的 TLS 握手如下圖所示:

優勢

  • 1)、「節省一次往返」

  • 2)、「省掉用於協商共享加密密鑰的公鑰加密計算」

缺點

對於那些每天都要“接待”幾萬甚至幾百萬獨立連接的服務器來說,由於每個打開的 TLS 連接都要佔用內存,因此需要一套會話 ID 緩存和清除策略。

爲了解決上述服務器端部署 TLS 會話緩存的問題,“會話記錄單” 機制出現了。

2)、會話記錄單(Session Ticket, RFC 5077)

該機制不用服務器保存每個客戶端的會話狀態。只要客戶端表明其支持會話記錄單,則「服務器可以在完整 TLS 握手的最後一次交換中添加一條“新會話記錄單”(New Session Ticket)記錄,包含只有服務器知道的安全密鑰加密過的所有會話數據」

然後,客戶端將這個會話記錄單保存起來,在後續會話的 ClientHello 消息中,可以將其包含在 SessionTicket 擴展中。這樣,所有會話數據只保存在客戶端,而由於 數據被加密過,且密鑰只有服務器知道,因此仍然是安全的。

會話標識符和會話記錄單機制,即“會話緩存”或“無狀態恢復”機制。其優點「主要是消除了服務器端的緩存負擔,通過要求客戶端在與服務器建立新連接時提供會話記錄單簡化了部署(除非記錄單過期)」

4、信任鏈與證書頒發機構

「身份驗證即用自己的私鑰簽名,然後對方用自己的公鑰驗證收到的消息簽名」。但信任是交流的關鍵。

對於瀏覽器來說,它信任誰呢?

「至少有三個答案」

  • 1)、「手工指定證書:所有瀏覽器和操作系統都提供了一種手工導入信任證書的機制」

  • 2)、「CA(Certificate Authority,證書頒發機構):被證書接受者(擁有者)和依賴證 書的一方共同信任的第三方」

  • 3)、「瀏覽器和操作系統:其中都會內置一個知名證書頒發機構的名單。因此,你也會信任操作系統及瀏覽器提供商提供和維護的可信任機構」

最常見的方案,就是瀏覽器指定可信任的證書頒發機構(根 CA)。而 「證書頒發機構簽署數字證書的流程」 如下圖所示:

所有瀏覽器都允許用戶檢視自己安全連接的信任鏈,「常見的訪問入口就是地址欄頭兒上的鎖圖標」,點擊即可查看。如下圖所示:

「整個鏈條的“信任依據”是根證書頒發機構,而每個瀏覽器都會內置一個可信任的證書頒發機構(根機構)的名單」

5、證書撤銷

通信的任何一端都可以根據嵌入的指令和簽名檢查鏈條中每個證書的狀態。

1)、CRL(Certificate Revocation List,證書撤銷名單) (RFC 528)

  • 「每個證書頒發機構維護並定期發佈已撤銷證書的序列號名單」

  • 「任何想驗證證書的人都可以下載撤銷名單,檢查相應證書是否榜上有名。如果有,說明證書已經被撤銷了」

缺點

  • 1)、「CRL 名單會隨着要撤銷的證書增多而變長,每個客戶端都必須取得包含所有序列 號的完整名單」

  • 2)、「沒有辦法立即更新剛剛被撤銷的證書序列號,比如客戶端先緩存了 CRL,之後某 證書被撤銷,那到緩存過期之前,該證書將一直被視爲有效」

2)、OCSP(Online Certificate Status Protocol,在線證書狀態協議)(RFC 2560)

  • 「一種實時檢查證書狀態的機制」

  • 「支持驗證端直接查詢證書數據庫中的序列號,從而驗證證書鏈是否有效」

缺點

  • 1)、「證書頒發機構必須處理實時查詢」

  • 2)、「證書頒發機構必須確保隨時隨地可以訪問」

  • 3)、「客戶端在進一步協商之前阻塞」 OCSP 請求。

  • 4)、「由於證書頒發機構知道客戶端要訪問哪個站點,因此實時 OCSP 請求可能會泄露 客戶端的隱私」

現實中,「CRL 和 OCSP 機制是互補存在的,大多數證書既提供指令也支持查詢」

6、TLS 記錄協議

TLS 記錄協議負責 「識別不同的消息類型(握手、警告或數據,通過“內容類型”字段),以及每條消息的安全和完整性驗證」。TLS 記錄結構如下圖所示:

交付應用數據的典型流程如下:

  • 1)、「記錄協議接收應用數據」

  • 2)、「接收到的數據被切分爲塊:最大爲每條記錄 214 字節,即 16 KB」

  • 3)、「壓縮應用數據(可選)」

  • 4)、「添加 MAC(Message Authentication Code)或 HMAC」

  • 5)、「使用商定的加密套件加密數據」

之後,加密數據就會被交給 TCP 層傳輸。「接收端的流程」 相同,順序相反:「使用商定的加密套件解密數據、驗證 MAC、提取並把數據轉交給上層的應用」

缺點

  • 1)、「TLS 記錄最大爲 16 KB」;

  • 2)、「每條記錄包含 5 字節的首部、MAC(在 SSL 3.0、TLS 1.0、TLS 1.1 中最多 20 字節,在 TLS 1.2 中最多 32 字節),如果使用塊加密則還有填充」;

  • 3)、「必須接收到整條記錄才能開始解密和驗證」

7、TLS 優化 Tips

1)、儘早完成握手

使用 CDN,在世界各地的服務器上緩存或重複部署數據和服務,而不需要讓所有用戶都通過跨海或跨大陸光纜連接到一箇中心原始服務器。

優勢

  • 1)、「通過使用本地代理服務器分流負載等手段降低延遲」

  • 2)、「本地代理服務器也可以與原始服務器建立一批長期的安全連接,全權代理請求與響應」

  • 3)、「在 CDN 中,客戶端連接終止於鄰近 CDN 節點,該節點將請求轉發到與對端服務器鄰近的 CDN 節點,之後請求才會被路由到原始服務器。這可以讓數據在優化的 CDN 骨幹網中尋路,從而進一步減少客戶端與服務器之間的延遲」

2)、使用會話緩存與無狀態恢復

  • 在大多數服務器的默認配置下它是禁用的,我們需要手動開啓它。

  • 在支持的客戶端中使用會話記錄單,而在不支持的客戶端中使用會話標識符。

3)、TLS 記錄大小

小記錄會造成浪費,大記錄會導致延遲。最優 TLS 記錄大小的參考值如下所示:

  • 「IPv4 幀需要 20 字節,IPv6 需要 40 字節」;

  • 「TCP 幀需要 20 字節」;

  • 「TCP 選項需要 40 字節(時間戳、SACK 等)」

「默認情況下,OpenSSL 等常用的庫會給每個連接分配 50 KB 空間,而谷歌的服務器把 OpenSSL 緩衝區的大小減少到 了大約 5KB。因此,我們需要在保障功能的前提下儘可能使用最小的內存」

4)、證書鏈的長度

瀏覽器怎麼知道到哪裏去找證書呢?

因爲 「子證書中通常包含父證書的 URL」

我們應該確保證書鏈的長度最小。「如果證書鏈長度超過了 TCP 的初始擁塞窗口,那我們無意間就會讓握手多了一次往返:證書長度超過擁塞窗口,從而導致服務器停下來等待 客戶端的 ACK 消息」

對此,有 「兩種解決方式」

  • 1)、「增大擁塞窗口」

  • 2)、「減少證書大小」

    • 「儘量減少中間證書頒發機構的數量:理想情況下,發送的證書鏈應該只包含兩個 證書:站點證書和中間證書頒發機構的證書。第三個證書,也就是根證書頒發機構的證書,已經包含在瀏覽器內置的信任名單中了,不用發送」

    • 「理想的證書鏈應該在 2 KB 或 3 KB 左右」

5)、OCSP 封套

服務器可以在證書鏈中包含(封套)證書頒發機構的 OCSP 響應,讓瀏覽器跳過在線查詢。把查詢 OCSP 操作轉移到服務器可以讓服務器緩存簽名的 OCSP 響應,從而節省很多客戶端的請求。

6)、HTTP 嚴格傳輸安全(HSTS,Strict Transport Security)

「一種安全策略機制,讓服務器通過簡單的 HTTP 首部(如 Strict-Transport-Security: max-age=31536000) 對適用的瀏覽器聲明訪問規則」

max-age 以秒爲單位指定 HSTS 規則集的生存時間(例如,max-age=31536000 等於 緩存 365 天)。

優勢

「HSTS 通過把責任轉移到客戶端,讓客戶端自動把所有鏈接重寫爲 HTTPS,消除了從 HTTP 到 HTTPS 的重定向損失」

我們需要熟練掌握 openssl 命令行工具,通過它來檢查整個握手和本地服務器配 置情況。其使用如下所示:

quchao@quchaodeMacBook-Pro paxgo % openssl s_client -state -CAfile startssl.ca.crt -connect igvita.com:443

4482293356:error:02FFF002:system library:func(4095):No such file or directory:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.11.1/libressl-2.8/crypto/bio/bss_file.c:122:fopen('startssl.ca.crt', 'r')
4482293356:error:20FFF080:BIO routines:CRYPTO_internal:no such file:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.11.1/libressl-2.8/crypto/bio/bss_file.c:125:
4482293356:error:0BFFF002:x509 certificate routines:CRYPTO_internal:system lib:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.11.1/libressl-2.8/crypto/x509/by_file.c:248:
CONNECTED(00000005)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = igvita.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
 0 s:/CN=igvita.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFXTCCBEWgAwIBAgISBJN+3MX9OKjS5cX4b6ww/vtAMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA0MjAxMzI1NDNaFw0y
MDA3MTkxMzI1NDNaMBUxEzARBgNVBAMTCmlndml0YS5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCx5ZoBTHLEUmRbkMVyBESzjCR1Oz9aop5aQRAp
bviLSasQbKaXp1DkzaB10am9Nr3ROKtP6tQgB8suaYC94I4SatnJsB3EBGew5GUr
MKybvoQYp4HzJvC49uUZDWFOlWdw6P5ldVXjsX22ATobK5XY0Tr1Ci5j7goanXRF
49sZ6yT5xVsKjprdg8/aoqtIDYXvJsZfJiDyGVung3Qb8RbmjlPvvGS7AXESSA8b
3g7lMdRBhsRPL7BXuVVnoU5CsPcTc7GPuJ5z0Qbfa34NILq4zPqvgH1pWRNJX7Fn
S7Hf5RVhlsuiCEr7BheVGWOjujuxFPOnPkoQ4EcfP6iGBITRAgMBAAGjggJwMIIC
bDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJbxqiGGEZ5EEEWj1p1RWhYRU/ESMB8G
A1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMwYTAu
BggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZzAv
BggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8w
JQYDVR0RBB4wHIIKaWd2aXRhLmNvbYIOd3d3Lmlndml0YS5jb20wTAYDVR0gBEUw
QzAIBgZngQwBAgEwNwYLKwYBBAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDov
L2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEFBgorBgEEAdZ5AgQCBIH2BIHzAPEAdwBv
U3asMfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAXGX+wdyAAAEAwBIMEYC
IQC55PavTz4OWvcbMpDNQIcR/SYEDvdSkqrYjxDRGx4vawIhAOCcGF3LKximqSmf
ch6R1EuZo/WTDzPioxM7X3w3kvFAAHYAB7dcG+V9aP/xsMYdIxXHuuZXfFeUt2ru
vGE6GmnTohwAAAFxl/sHcgAABAMARzBFAiBUlTes9VFQ56gbUgRq/7fFUVi6r4Eo
sWHADNNsQ7BSIgIhAPyfR9jDpnHQi3cqjRV2lBp0rrLAcEKf+b4cpDUvw41NMA0G
CSqGSIb3DQEBCwUAA4IBAQBGvck8LK6h8zMxA6bNpxW5Md6K/cUA/HlS0GUiOlnh
9IWZfg3t96Co9d8i90tqjm2gGRVDk7ywiGUClFky6EPICTka0VQRwgLI6aIvh9OF
8syf0QijfXUIkFRZNxGRkAsFqPsbAbDc6+hUMOWQY/uw2yITLB0eS+HyRAZWszoJ
IS4b/Y/gHvnkF/d+y792Y61pf9qtuuTgV/Wdb/KtxJtHKOPVn2eMF7omwyQfqF5o
CijVj/znJBaq9f/8BerL76qRTgeJeM8z0H18ZRpplMyS0T/k1QRTIq6c8lpOt887
PP2IVI8v3WlgNtlZ8XypmZdBjQtncaB1S2MmKgqas5Dx
-----END CERTIFICATE-----
subject=/CN=igvita.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 3093 bytes and written 354 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: CF508DEBB4768BBB308095B730EB0FBC7F21C53095AE8DF2E0905D085F98F158
    Session-ID-ctx:
    Master-Key: BEF07A818F91C840EF60A4DB5AEE89A1107EB594BC4718D7B4E2FC6904289AE7E7DB2CF6497812A82CCFD23F33B915B6
    Start Time: 1590415033
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
SSL3 alert read:warning:close notify
closed
SSL3 alert write:warning:close notify
複製代碼

其中需要了解 「四處關鍵信息」

  • SSL_connect「SSLv3 read server done A:客戶端完成對接收到的證書鏈的驗證」

  • Certificate chain「接收到的證書鏈(2 個證書)」

  • SSL handshake has read 3093 bytes and written 354 bytes「接收到證書鏈的大小」

  • Session-ID「對有狀態 TLS 恢復發送的會話標識符」

六、無線網絡性能

1、無線網絡的類型

  • 「個人局域網(PAN)」

  • **局域網(LAN) **

  • **城域網(MAN) **

  • 「廣域網(WAN)」

2、無線網絡的性能基礎

1)、信道容量(最大信息速率)

C= BW × log2(1+S/N)
複製代碼
  • C 是信道容量,單位是 bit/s;

  • BW 是可用帶寬,單位是 Hz;

  • S 是信號,N 是噪聲,單位是 W。

「它涵蓋了影響大多數無線網絡性能的所有基本因素」

2)、帶寬

爲實現通信,「發送端與接收端必須事先就通信使用的頻率範圍達成共識」,在這個頻率範圍內雙方纔可以順暢地交換信息。

影響性能的最主要因素就是頻率範圍的大小(帶寬)。由信道容量的公式可知,信道的總體比特率與分配的帶寬呈正比。

3)、信號強度

信噪比(SNR,Signal Noise Ratio),「它衡量的是預期信號強度與背景噪聲及干擾之間的比值」。背景噪聲越大,攜帶信息的信號就必須越強。

「如果想在存在干擾的情況下達到預期的數據傳輸速度,要麼增大 發射功率,也就是提高信號強度,要麼縮短收發兩端的距離——或者雙管齊下」

路徑損耗(通路衰減)

「信號強度隨距離降低」

遠近效應

接收端捕獲較強的信號,因而不可能檢測到較弱的信號,實際上是“擠出”了較弱的信號。例如你旁邊一個或多個大聲講話的人會阻擋較弱的信號,從而產生遠近效應。

小區呼吸效應

小區覆蓋範圍或信號傳輸距離基於噪聲大小和干擾級別擴展和收縮。例如你周圍交談的人越多,干擾就越嚴重,能讓你識別有用信號的範圍也越小,這就是呼吸效應。

4)、調製

「數字信號(1 和 0)需要轉換成模擬信號(無線電波)」。調製指的就 是這個數模轉換過程,而不同調制算法的轉換效率是不一樣的。

但是,「高階調製的代價是針對噪聲和干擾的可靠性降低」。因此,需要在它們與轉換效率直接做一個權衡。

3、影響無線網絡性能的因素

  • 「收發端的距離」;

  • 「當前位置的背景噪聲大小」;

  • 「來自同一網絡(小區)其他用戶的干擾大小」;

  • 「來自相鄰網絡(小區)其他用戶的干擾大小」;

  • 「兩端發射功率大小」;

  • 「處理能力及調製算法」

七、Wi-Fi

Wi-Fi 可以用來指稱任何基於 IEEE 802.11 標準的產品。它工作於免許可的 2.4 GHz ISM 頻段。

1、從以太網到無線局域網

在 1971 年夏威夷大學對外公佈了第一個關於無線網絡的協議— ALOHAnet 協議。

以太網協議很大程度上借鑑了 ALOHAnet 協議,以太網通常被稱作局域網(LAN)標準,而 802.11 無線標準主要是作爲既有以太網標準(802.3)的擴展來設計的。因此它也相應地被稱作無線局域網(WLAN,Wireless LAN )標準。

1)、以太網—衝突檢測(CSMA/CD,Collision Detection)機制

如果檢測到衝突,則雙方都立即停止發送數據並小睡一段隨機的時間(後續時間以指數級增長),從而保證發生衝突 的發送端不會同步,且不會同時重新開始發送數據。

2)、Wi-Fi-衝突避免(CSMA/CA, Collision Avoidance)機制

由於收發無線電的硬件所限,它不能在發送數據期間檢測到衝突。因此,每個發送方都會在自己認爲信道空閒時發送數據,以避免衝突。

2、Wi-Fi 優化 Tips

1)、利用不計流量的帶寬

2)、適應可變帶寬

比如自適應比特流,來主動適應帶寬變化。自適應比特率並不適合所有資源,但對視頻和音頻這樣的長時間流服務是非常合適的。

在客戶端下載視頻流期間,客戶端或服務器可以監控每個視頻塊的下載速度,必要時根據帶寬的變化調整要下載的下一個視頻塊的比特率。事實上,現實中的視頻服務,「開始一般是低比特率的視頻塊,以便視頻播放能更快開始。然後,再根據可用帶寬的動態變化調整後續視頻塊的比特率」

深入探索 Android 網絡優化(二、網絡優化基礎篇)下


作者:jsonchao
鏈接:https://juejin.im/post/5ecf149af265da76ce577fbc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章