1. 程式人生 > >瀏覽器中常見網絡協議介紹

瀏覽器中常見網絡協議介紹

響應 網絡 ebs 優化 system 目標 其他 有序 ipv

本周五我在公司有一個關於《HTTP 協議》的培訓,只有兩個小時,估計能講到的東西不會太多。實際上,瀏覽器為了完成 WEB 應用的各項功能,需要跟各種網絡協議打交道,HTTP 只是其中一種。本文會介紹瀏覽器中常見的網絡協議,以及各種協議之間的關系。

我們經常會聽到「TCP/IP 協議」這個名詞,從字面上看,有人會認為它專指 TCP 和 IP 兩種協議。實際上大多數情況,TCP/IP 協議指的是整個網際協議族(Internet Protocol Suite),是利用 IP 協議進行通訊的其他協議統稱。TCP/IP 包含的協議眾多,還有一個分層模型。相比較 OSI 模型,TCP/IP 的分層更簡單,從下到上分別為:物理層、數據鏈路層、網絡層、傳輸層和應用層。

IP(Internet Protocol)屬於網絡層協議,負責聯網主機之間的路由選擇和尋址。IPv4 中的 4 指的是 TCP/IP 協議的第 4 個版本,直到這個版本,IP 協議才單獨拆出來,所以並沒有單獨的 IPv1 - IPv3。而 IPv5 分給了一個沒什麽進展的試驗性協議,所以下一個版本的 IP 協議變成了 IPv6。

TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是整個 TCP/IP 協議中最重要的兩個傳輸層協議。TCP 是面向連接的、可靠的流協議;UDP 是不具有可靠性的數據報協議。後面可以看到,對可靠性要求比較高的上層協議一般會基於 TCP;而對高速傳輸和實時性有較高要求的上層協議一般會基於 UDP。

介紹完比較低層的 IP、TCP 和 UDP 之後,下面看幾個瀏覽器中常見的應用層協議。

HTTP 與 WebSocket

HTTP 協議是瀏覽器需要用到的最重要的網絡協議,它包括很多版本,例如最常見的 HTTP/1.1,剛剛發布的 HTTP/2,還有 Google 實現的過渡版本 SPDY 等等。本文不討論 HTTP 的細節以及各版本之間的差異,只打算列出 HTTP 與其他協議 / 應用之間的關系,見下圖:

+-------------+-------------+--------------+
|     XHR     |     SSE     |      WS      |
+-------------+-------------+------+       +
|               HTTP               |       |
+----------------------------------+-------+
|                    TLS *                 |
+------------------------------------------+
|                    TCP                   |
+------------------------------------------+
|                    IP                    |
+------------------------------------------+

從上圖可以看出 HTTP 是在 TCP 之上實現的,所以 HTTP 中並不需要關註數據傳輸的可靠性,類似於順序控制、重發這樣的機制在傳輸層已經有了。同時,HTTP 也擁有 TCP 的一些缺點,給 WEB 性能優化帶來挑戰。

XHR(XmlHTTPRequest)和 SSE(Server-Sent Events)都是瀏覽器提供的數據交互功能,它們的本質都還是 HTTP。XHR 是 Ajax 技術的核心,大家都很熟,這裏略過不討論;SSE 概念還算新,多說幾句。我們知道 HTTP 只能由客戶端發起請求,再由服務端響應。SSE 也是這樣,只不過服務端會保持住這個 HTTP 連接,多次發送響應,不像平時發送完響應就結束了。實際上,很早之前在 WebIM 中類似的 HTTP 長連接技術就已經很盛行了,有興趣的同學可以看下這篇八年前的文章:Comet:基於 HTTP 長連接的「服務器推」技術。

既然 XHR 和 SSE 本質都是 HTTP 連接,所以 HTTP 協議中一些常見概念,例如請求方式(GET、POST 等),請求響應頭部(Cookie、內容編碼、傳輸編碼、緩存等)等等,依然存在。

而 WS(WebSocket)是直接基於 TCP 實現的,HTTP 協議中的那些概念都不復存在。需要註意的是,從前面圖表中可以看出,它還是依賴於 HTTP,這是因為 WebSocket 握手利用了 HTTP 的 Upgrade 機制。一旦握手完成,後續數據傳輸就直接在 TCP 上完成。瀏覽器中新協議借助 HTTP 作為引導,是一個較為普遍的做法。

TLS(Transport Layer Security,傳輸層安全),作用是保證數據在傳輸過程中的完整性和保密性,屬於可選項。啟用了 TLS 之後,HTTP 協議的 URL 前綴需要由 http:// 改成 https://;WebSocket 協議的 URL 前綴需要由 ws:// 改成 wss://

DNS

DNS(Domain Name System),就是大家熟知的域名解析服務,提供了從域名到 IP 的轉換。瀏覽器中大部分網絡交互都會使用域名,而傳輸層協議需要的是 IP,所以 DNS 是基礎。

+-------------------------------+
|              DNS              |
+-------------------------------+
|      TCP      |      UDP      |
+---------------+---------------+
|               IP              |
+-------------------------------+

DNS 服務默認使用 UDP 協議獲得查詢結果,通常僅當結果超過 512 字節或者進行 DNS 服務器同步時才會使用 TCP 協議。這是因為 DNS 的使用非常頻繁,又是基礎,響應速度是優先需要考慮的。使用 UDP 可以滿足速度上的要求,但同時也引入了類似於「DNS 緩存投毒」這類問題。

WebRTC

WebRTC(Web Real-Time Communication)出現之前,DNS 幾乎是瀏覽器唯一使用的基於 UDP 的協議。WebRTC 提供的三大功能中,MediaStream 與網絡無關,RTCPeerConnection 和 RTCDataChannel 都是基於 UDP,如圖:

+-----------------------+-------------------------+
|   RTCPeerConnection   |      RTCDataChannel     |
+-----------------------+-------------------------+
|          SRTP         |           SCTP          |
+             +---------+-------------------------+
|             |                DTLS               |
+-------------+-----------------------------------+
|                ICE, STUN, TURN                  |
+-------------------------------------------------+
|                       UDP                       |
+-------------------------------------------------+
|                       IP                        |
+-------------------------------------------------+

這個圖比較復雜,我們從下往上介紹:

ICE(Interactive Connectivity Establishment)框架,作用是在端與端之間建立一條有效的通道,優先直連,其次用 STUN 協商,再不行只能用 TURN 轉發:

  • STUN(Session Traversal Utilities for NAT)協議,解決了三個問題:1)獲得外網 IP 和端口;2)在 NAT 中建立路由條目,綁定外網端口,使得到達外網 IP 和端口的入站分組能找到應用程序,不被丟棄;3)定義了一個簡單的 keep-alive 機制,保證 NAT 路由條目不會因為超時而被刪除。STUN 服務器必須架設在公網上,可以自己搭建,也可以使用第三方提供的公開服務,例如 Google 的「stun:stun.l.google.com:19302」。
  • TURN(Traversal Using Relays around NAT)協議,依賴外網中繼設備在兩端之間傳遞數據。簡單說就是通過兩端都可以訪問的 TURN 服務轉發消息,間接把兩端連起來。

DTLS(Datagram Transport Layer Security,數據報傳輸層安全),本質上就是 TLS,只是為了兼容 UDP 的數據報傳輸而做了一些微小的修改,可以簡單把它理解為 UDP 版的 TLS。

再往上就兵分兩路,一路的目標是 RTCPeerConnection,負責音頻和視頻數據通信,對傳輸速度和實時性有很高的要求,這裏又有兩個新的協議出現:

  • SRTP(Secure Real-time Transport Protocol,安全實時傳輸協議)。WebRTC 中的音頻和視頻等實時數據都是通過這個協議傳輸。它是 RTP 協議的安全版。
  • SRTCP(Secure Real-Time Control Transport Protocol,安全實時控制傳輸協議)。它會跟蹤 SRTP 的運行情況,以便調整每個流的發送速率、編碼品質和其他參數。它是 RTCP 協議的安全版。

另一路的目標是 RTCDataChannel,用來在端到端之間傳輸任意應用數據,SRTP 是專門為傳輸媒體數據為設計的,不適合傳輸應用數據,所以這裏又需要一個新的協議:

  • SCTP(Stream Control Transmission Protocol,流控制傳輸協議)。本身 SCTP 是一個傳輸層協議,直接運行在 IP 協議之上,與 TCP 和 UDP 類似。但在 WebRTC 這裏,SCTP 卻運行於 DTLS 之上。SCTP 很好的一點是提供了交付屬性選項,使用者可以指定消息是有序還是亂序,是可靠還是部分可靠,部分可靠時還可以指定使用超時重傳還是計數重傳策略。

QUIC

Google 正在試驗一種新的傳輸層協議:QUIC(Quick UDP Internet Connections),它的本質是基於 UDP 實現 HTTP,相當於之前的 TCP + TLS。從目前的資料來看,QUIC 可以大幅減少建立連接的時間,這是通過簡化握手步驟從而減少 RTT(Round-Trip Time)來實現的,類似於 TFO(TCP Fast Open)。有興趣的同學可以點這個連接圍觀,據說 Google 自家服務來自 Chrome 的請求中,已經有 50% 使用了 QUIC 協議。

最後表達下對 Google 的佩服。Google 為了優化 WEB 性能,在瀏覽器(Chrome)、排版引擎(Blink)、JS 引擎(V8)、圖片格式(WebP)、傳輸層協議(TCP 的 TFO,QUIC)、應用層協議(SPDY)以及 HTML5(從 Google Gears 開始)等等方面都做了大量努力,實在是技術型公司典範,嘆為觀止!

瀏覽器中常見網絡協議介紹