1. 程式人生 > >你要問我應用層?我就和你扯扯扯

你要問我應用層?我就和你扯扯扯

網路應用是計算機網路存在的理由,一批早起的網路應用主要有電子郵件、遠端訪問、檔案傳輸等,但是隨著計算機網路的發展和人類無窮無盡的需求,越來越多的網路應用被開發出來,例如即時通訊和對等(P2P)檔案共享,IP 電話、視訊會議等。還有一些多方線上遊戲被開發出來如《魔獸世界》等,可以說計算機網路是一切應用演變出來的基礎。人要懷有一顆感恩的心,感謝這些前輩的努力,才讓我們現在的生活如此豐富多彩。但是我們作為程式設計師,不僅要能夠享受這些成果,還要知道為什麼,這樣生活才會和諧。

應用層協議原理

研發網路應用程式的核心是寫出能夠執行在不同的端系統和通過網路彼此通訊的程式。例如,在網路應用程式中,有兩個互相通訊的不同程式:一個是執行在使用者主機上的瀏覽器程式;另一個是執行在 Web 伺服器主機上的 Web 伺服器程式。

網路應用程式體系結構

網路應用程式的體系結構(application architecture)主要有兩種,一種是 客戶-伺服器體系結構(client-server architecture) ,在客戶-伺服器體系結構中,有一個持續開啟,等待連線的主機稱為伺服器,它服務於來自許多其他稱為 客戶 的主機請求。比如 Web 伺服器總會等待來自瀏覽器(執行在客戶主機上)的請求。注意這種客戶-伺服器體系結構中,客戶之間是不會彼此交流資訊的,它們只與相應的伺服器進行通訊。還有一點是伺服器具有固定的 IP 地址。下圖顯示了這種體系結構

這種客戶-伺服器體系結構存在弊端,那就是有的時候伺服器的響應跟不上客戶請求速度的情況,鑑於此,這種體系結構需要經常配備資料中心(data center)

用來建立更強大的伺服器。例如搜尋引擎(谷歌、Bing和百度)網際網路商店(亞馬遜、e-Bay 和阿里巴巴)、基於 Web 的電子郵件(Gmail 和 雅虎)社交網路(臉書、Instagram、推特和微信),就是用了多個數據中心。

另外一種體系結構是 P2P體系結構(P2P architecture),相對於對資料中心有過多依賴的客戶-伺服器體系結構,P2P 體系結構則直接通過兩臺相連的主機直接通訊,這些主機稱為對等方。典型的 P2P 體系結構的應用包括 檔案共享(BitTorrent)下載器(迅雷)網際網路電話和視訊會議(Skype),下圖顯示了 P2P 體系結構圖

P2P 體系結構最重要的一個特性就是它的自擴充套件性(self-scalability)

。例如,在一個 P2P 檔案共享的應用中,儘管每個對等方都由於請求檔案產生工作負載,但每個對等方通過向其他對等方分發檔案也為系統增加伺服器能力。

程序通訊

我們上面說到了兩種體系結構,一種是客戶-伺服器模式,一種是P2P 對等模式。我們都知道一個計算機允許同時執行多個應用程式,在我們看起來這些應用程式好像是同時執行的,那麼它們之間是如何通訊的呢?不可能存在同是一個母親,兄弟倆不交流的情況吧。

用作業系統的術語來說,進行通訊實際上是 程序(process)而不是程式。一個程序可以被認為是執行在端系統中的程式。當多個程序執行在相同的端系統上,它們使用程序間的通訊機制相互通訊。程序間的通訊規則由作業系統來確定。我們暫不關心執行在同一主機上不同應用程式是如何通訊的,我們主要探討的目標是不同端系統中兩個程序是如何通訊的。還是分為兩種結構來探討。

客戶和伺服器程序

網路應用程式由成對的程序組成,這些程序通過網路相互發送報文。例如,在 Web 應用程式中,檔案從一個對等方中的程序傳輸到另一個對等方中的程序。而在每對通訊的程序中,都會有一對客戶(client)伺服器(server) 存在。比如我們上面提到的 Web ,對於 Web 來說,瀏覽器是一個客戶程序,而 Web 伺服器是一臺伺服器程序。也許你也應該能猜到,在 P2P 體系結構中,一個程序能夠扮演兩種角色,既是客戶又是伺服器的情況。但是在實際通訊的過程中,我們還是很容易區分的,我們通常通過下面這種方式進行區分。

在一對程序之間的通訊會話場景中,發起通訊(即在會話開始時發起與其他程序的聯絡)的程序稱為客戶,在會話開始時等待聯絡的被稱為伺服器

程序與計算機網路之間的介面

計算機是龐大且繁雜的,計算機網路也是,應用程式不可能只有一個程序組成,它同樣是多個程序共同作用協商執行,然而,分佈在多個端系統之間的程序是如何進行通訊的呢?實際上,每個程序之間會有一個 套接字(socket) 的軟體介面存在,套接字是應用程式的內部介面,應用程式可以通過它傳送或接收資料,可對其進行像對檔案一樣的開啟、讀寫和關閉等操作。套接字允許應用程式將 I/O 插入到網路中,並與網路中的其他應用程式進行通訊。

通過一個例項來簡單類比一下套接字和網路程序:程序可類比一座房子,而它的套接字相當於是房子的門,當一個程序想要與其他程序進行通訊時,它會把報文推出門外,然後通過運輸裝置把報文運輸到另外一座房子,通過門進入房子內部使用。

下圖是一個通過套接字進行通訊的流程圖

從圖可以看到,Socket 屬於主機或者服務程序的內部介面,由應用程式開發人員進行控制,兩臺端系統之間進行通訊會通過 TCP 的緩衝區經由網路傳輸到另一個端系統的 TCP 緩衝區,Socket 從 TCP 緩衝區讀取報文供應用程式內部使用。

套接字是建立網路應用程式的可程式設計介面,因此套接字也被稱為應用程式和網路之間的 應用程式程式設計介面(Application Programming Interface,API)。應用程式開發人員可以控制套接字內部細節,但是無法控制運輸層的傳輸,只能對運輸層的傳輸協議進行選擇,還可以對運輸層的傳輸引數進行選擇,比如最大快取和最大報文長度等。

程序定址

我們上面提到網路應用程式之間會相互發送報文,那麼你怎麼知道你應該向哪裡傳送報文呢?是不是存在某種機制能夠讓你知道你能夠發到哪裡?這就好比你要傳送電子郵件,你寫好了內容但是你不知道發發往哪裡,所以這個時候必須要有一種知道對方地址的機制,這種機制能夠辨明對方唯一的一個地址,這種地址就是 IP地址。我們會在後面的文章中詳細討論 IP 地址的內容,目前只需要知道 IP 是一個32位元的量並且能夠唯一標示網際網路中任意一臺主機的地址就可以了。

只知道 IP 地址是否就可以了呢?我們知道一臺計算機可能回執行多個網路應用程式,那麼如何確定是哪個網路應用程式接受傳送過來的報文呢?所以這時候還需要知道網路應用程式的 埠號(port number)。例如, Web 應用程式需要用 80 埠來標示,郵件伺服器程式需要使用 25 來標示。

應用程式如何選擇運輸服務

我們知道應用程式是屬於網際網路四層協議的 應用層 協議,並且四層協議必須彼此協助共同完成工作。好了,這時候我們只有應用層協議,我們需要傳送報文,我們如何傳送報文呢?這就好比你知道目的地是哪裡了,你該如何到達目的地呢?是走路,公交,地鐵還是打車?

應用程式傳送報文的交通工具的選擇也有很多,我們可以從 資料傳輸是否可靠、吞吐量、定時和安全性 來考慮,下面是你需要考慮的具體內容。

  • 資料傳輸是否可靠

我們之前探討過,分組在計算機網路中會存在丟包問題,丟包問題的嚴重性跟網路應用程式的性質有關,如果像是電子郵件、檔案傳輸、遠端主機、Web 文件傳輸的過程中出現問題,資料丟失可能會造成非常嚴重的後果。如果像是網路遊戲,多人視訊會議造成的影響可能比較小。鑑於此,資料傳輸的可靠性也是首先需要考慮的問題。因此,如果一個協議提供了這樣的確保資料交付的服務,就認為提供了 可靠資料傳輸(reliable data transfer),能夠忍受資料丟失的應用被稱為 容忍丟失的應用(loss-tolerant application)

  • 吞吐量

在之前的文章中我們引入了吞吐量的概念,吞吐量就是在網路應用中資料傳輸過程中,傳送程序能夠向接收程序交付位元的速率。具有吞吐量要求的應用程式被稱為 頻寬敏感的應用(bandwidth-sensitive application)。頻寬敏感的應用具有特定的吞吐量要求,而 彈性應用(elastic application) 能夠根據當時可用的頻寬或多或少地利用可供使用的吞吐量。

  • 定時

定時是什麼意思?定時能夠確保網路中兩個應用程式的收發是否能夠在指定的時間內完成,這也是應用程式選擇運輸服務需要考慮的一個因素,這聽起來很自然,你網路應用傳送和接收資料包肯定要加以時間的概念,比如在遊戲中,你一包資料遲遲傳送不過去,對面都推塔了你還卡在半路上呢。

  • 安全性

最後,選擇運輸協議一定要能夠為應用程式提供一種或多種安全性服務。

因特網能夠提供的運輸服務

說完運輸服務的選型,接下來該聊一聊因特網能夠提供哪些服務了。實際上,因特網為應用程式提供了兩種運輸層的協議,即 UDPTCP,下面是一些網路應用的選擇要求,可以根據需要來選擇適合的運輸層協議。

應用 資料丟失 頻寬 時間敏感
檔案傳輸 不能丟失 彈性 不敏感
電子郵件 不能丟失 彈性 不敏感
Web 文件 不能丟失 彈性 不敏感
因特網電話/視訊會議 容忍丟失 彈性 敏感,100ms
流式儲存音訊/視訊 容忍丟失 彈性 敏感,幾秒
互動式遊戲 容忍丟失 彈性 是,100ms
智慧手機訊息 不能丟失 彈性 無所謂

下面我們就來聊一聊這兩種運輸協議的應用場景

TCP

TCP 服務模型的特性主要有下面幾種

  • 面向連線的服務

在應用層資料報傳送後, TCP 讓客戶端和伺服器互相交換運輸層控制資訊。這個握手過程就是提醒客戶端和伺服器需要準備好接受資料報。握手階段後,一個 TCP 連線(TCP Connection) 就建立了。這是一條全雙工的連線,即連線雙方的程序都可以在此連線上同時進行收發報文。當應用程式結束報文傳送後,必須拆除連線。

  • 可靠的資料傳輸

通訊程序能夠依靠 TCP,無差錯、按適當順序交付所有傳送的資料。應用程式能夠依靠 TCP 將相同的位元組流交付給接收方的套接字,沒有位元組的丟失和冗餘。

  • 擁塞控制

TCP 的擁塞控制並不一定為通訊程序帶來直接好處,但能為因特網帶來整體好處。當接收方和傳送方之間的網路出現擁塞時,TCP 的擁塞控制會抑制傳送程序(客戶端或伺服器),我們會在後面具體探討擁塞控制

UDP

UDP 是一種輕量級的運輸協議,它僅提供最小服務。UDP 是無連線的,因此在兩個程序通訊前沒有握手過程。UDP 也不會保證報文是否傳輸到服務端,它就像是一個撒手掌櫃。不僅如此,到達接收程序的報文也可能是亂序到達的。

下面是上表列出來的一些應用所選擇的協議

應用 應用層協議 支撐的運輸協議
電子郵件 SMTP TCP
遠端終端訪問 Telnet TCP
Web HTTP TCP
檔案傳輸 FTP TCP
流式多媒體 HTTP TCP
因特網電話 SIP、RTP TCP或UDP

應用層協議

現在我們會探討一些應用層協議,首先來認識一下什麼是 應用層協議,應用層協議(application-layer protocol) 定義了執行在不同端系統上的應用程序如何相互傳遞報文。

應用層協議會定義

  • 交換的報文型別,如請求報文和響應報文;
  • 各種報文型別的語法,如報文中的各個欄位公共詳細描述;
  • 欄位的語義,即包含在欄位中資訊的含義;
  • 程序何時、如何傳送報文及對報文進行響應。

應用層協議分類

  • 域名系統(Domain Name System, DNS):用於實現網路裝置名字到 IP 地址對映的網路服務。
  • 檔案傳輸協議(File Transfer Protocol,FTP):用於實現互動式檔案傳輸功能。
  • 郵件傳送協議(Simple Mail Transfer Protocol, SMTP):用於實現電子郵箱傳送功能。
  • 超文字傳輸協議(HyperText Transfer Protocol,HTTP):用於實現 Web 服務。
  • 遠端登入協議(Telnet):用於實現遠端登入功能。

Web 和 HTTP

Web(World Wide Web)即全球廣域網,也就是 URL 為 www 開頭的網路,它是 HTTP 協議的主要載體,是建立在 Internet 上的一種網路服務,我們一般講的 Web ,其實就是指的 HTTP 協議,HTTP 協議作為 web 程式設計師必須要掌握並理解的一門協議,有必要好好了解一下。

超文字傳輸協議可以進行文字分割:超文字(Hypertext)、傳輸(Transfer)、協議(Protocol),它們之間的關係如下

按照範圍的大小 協議 > 傳輸 > 超文字。下面就分別對這三個名次做一個解釋。

什麼是超文字

在網際網路早期的時候,我們輸入的資訊只能儲存在本地,無法和其他電腦進行互動。我們儲存的資訊通常都以文字即簡單字元的形式存在,文字是一種能夠被計算機解析的有意義的二進位制資料包。而隨著網際網路的高速發展,兩臺電腦之間能夠進行資料的傳輸後,人們不滿足只能在兩臺電腦之間傳輸文字,還想要傳輸圖片、音訊、視訊,甚至點選文字或圖片能夠進行超連結的跳轉,那麼文字的語義就被擴大了,這種語義擴大後的文字就被稱為超文字(Hypertext)

什麼是傳輸

那麼我們上面說到,兩臺計算機之間會形成互聯關係進行通訊,我們儲存的超文字會被解析成為二進位制資料包,由傳輸載體(例如同軸電纜,電話線,光纜)負責把二進位制資料包由計算機終端傳輸到另一個終端的過程(對終端的詳細解釋可以參考 你說你懂網際網路,那這些你知道麼?這篇文章)稱為傳輸(transfer)

通常我們把傳輸資料包的一方稱為請求方,把接到二進位制資料包的一方稱為應答方。請求方和應答方可以進行互換,請求方也可以作為應答方接受資料,應答方也可以作為請求方請求資料,它們之間的關係如下

如圖所示,A 和 B 是兩個不同的端系統,它們之間可以作為資訊交換的載體存在,剛開始的時候是 A 作為請求方請求與 B 交換資訊,B 作為響應的一方提供資訊;隨著時間的推移,B 也可以作為請求方請求 A 交換資訊,那麼 A 也可以作為響應方響應 B 請求的資訊。

什麼是協議

協議這個名詞不僅侷限於網際網路範疇,也體現在日常生活中,比如情侶雙方約定好在哪個地點吃飯,這個約定也是一種協議,比如你應聘成功了,企業會和你簽訂勞動合同,這種雙方的僱傭關係也是一種 協議。注意自己一個人對自己的約定不能成為協議,協議的前提條件必須是多人約定。

那麼網路協議是什麼呢?

網路協議就是網路中(包括網際網路)傳遞、管理資訊的一些規範。如同人與人之間相互交流是需要遵循一定的規矩一樣,計算機之間的相互通訊需要共同遵守一定的規則,這些規則就稱為網路協議。

沒有網路協議的網際網路是混亂的,就和人類社會一樣,人不能想怎麼樣就怎麼樣,你的行為約束是受到法律的約束的;那麼網際網路中的端系統也不能自己想發什麼發什麼,也是需要受到通訊協議約束的。

那麼我們就可以總結一下,什麼是 HTTP?可以用下面這個經典的總結回答一下: HTTP 是一個在計算機世界裡專門在兩點之間傳輸文字、圖片、音訊、視訊等超文字資料的約定和規範

永續性連線和非永續性連線

HTTP 是可以使用永續性連線和非永續性連線的,下面我們著重探討一下這兩種方式

非永續性連線

我們首先來探討一下永續性連線的 HTTP

你是不是很好奇,當你在瀏覽器中輸入網址後,到底發生了什麼事情?你想要的內容是如何展現出來的?讓我們通過一個例子來探討一下,我們假設訪問的 URL 地址為 http://www.someSchool.edu/someDepartment/home.index,當我們輸入網址並點選回車時,瀏覽器內部會進行如下操作

  • DNS 伺服器會首先進行域名的對映,找到訪問www.someSchool.edu所在的地址,然後 HTTP 客戶端程序在 80 埠發起一個到伺服器 www.someSchool.edu 的 TCP 連線(80 埠是 HTTP 的預設埠)。在客戶和伺服器程序中都會有一個套接字與其相連。
  • HTTP 客戶端通過它的套接字向伺服器傳送一個 HTTP 請求報文。該報文中包含了路徑 someDepartment/home.index 的資源,我們後面會詳細討論 HTTP 請求報文。
  • HTTP 伺服器通過它的套接字接受該報文,進行請求的解析工作,並從其儲存器(RAM 或磁碟)中檢索出物件 www.someSchool.edu/someDepartment/home.index,然後把檢索出來的物件進行封裝,封裝到 HTTP 響應報文中,並通過套接字向客戶進行傳送。
  • HTTP 伺服器隨即通知 TCP 斷開 TCP 連線,實際上是需要等到客戶接受完響應報文後才會斷開 TCP 連線。
  • HTTP 客戶端接受完響應報文後,TCP 連線會關閉。HTTP 客戶端從響應中提取出報文中是一個 HTML 響應檔案,並檢查該 HTML 檔案,然後迴圈檢查報文中其他內部物件。
  • 檢查完成後,HTTP 客戶端會把對應的資源通過顯示器呈現給使用者。

至此,鍵入網址再按下回車的全過程就結束了。上述過程描述的是一種簡單的請求-響應全過程,真實的請求-響應情況可能要比上面描述的過程複雜很多。

上面的步驟舉例說明了非永續性連線的使用,其中每個 TCP 連結都在伺服器傳送完成後關閉。每個 TCP 連線只傳輸一個請求報文和響應報文。

永續性連線的 HTTP

非永續性連線有一些缺點。第一,必須為每個請求的物件建立和維護一個全新的連線。對於每個這樣的連線來說,在客戶端和伺服器中都要分配 TCP 的緩衝區和保持 TCP 變數,這給 Web 伺服器帶來了嚴重的負擔。因為一臺 Web 伺服器可能要同時服務於數百甚至上千個客戶請求。

在採用 HTTP 1.1 持續連線的情況下,伺服器在傳送響應後保持該 TCP 連線開啟不關閉。在相同的客戶與伺服器之間,後續的請求和響應報文能夠通過相同的連線進行傳送。一般來說,如果一跳連線經過一定的時間間隔(可配置)後仍未使用,HTTP 伺服器就應該關閉其連線。

HTTP 報文格式

我們上面描述了一下 HTTP 的請求響應過程,流程比較簡單,但是凡事就怕認真,你這一認真,就能拓展出很多東西,比如 HTTP 報文是什麼樣的,它的組成格式是什麼? 下面就來探討一下

HTTP 協議主要由三大部分組成:

  • 起始行(start line):描述請求或響應的基本資訊;
  • 頭部欄位(header):使用 key-value 形式更詳細地說明報文;
  • 訊息正文(entity):實際傳輸的資料,它不一定是純文字,可以是圖片、視訊等二進位制資料。

其中起始行和頭部欄位併成為 請求頭 或者 響應頭,統稱為 Header;訊息正文也叫做實體,稱為 body。HTTP 協議規定每次傳送的報文必須要有 Header,但是可以沒有 body,也就是說頭資訊是必須的,實體資訊可以沒有。而且在 header 和 body 之間必須要有一個空行(CRLF),如果用一幅圖來表示一下的話,我覺得應該是下面這樣

我們使用上面的那個例子來看一下 http 的請求報文

如圖,這是 http://www.someSchool.edu/someDepartment/home.index 請求的請求頭,通過觀察這個 HTTP 報文我們就能夠學到很多東西,首先,我們看到報文是用普通 ASCII 文字書寫的,這樣保證人能夠可以看懂。然後,我們可以看到每一行和下一行之間都會有換行,而且最後一行(請求頭部後)再加上一個回車換行符。

每個報文的起始行都是由三個欄位組成:方法、URL 欄位和 HTTP 版本欄位。

HTTP 請求方法

HTTP 請求方法一般分為 8 種,它們分別是

  • GET 獲取資源,GET 方法用來請求訪問已被 URI 識別的資源。指定的資源經伺服器端解析後返回響應內容。也就是說,如果請求的資源是文字,那就保持原樣返回;

  • POST 傳輸實體,雖然 GET 方法也可以傳輸主體資訊,但是便於區分,我們一般不用 GET 傳輸實體資訊,反而使用 POST 傳輸實體資訊,

  • PUT 傳輸檔案,PUT 方法用來傳輸檔案。就像 FTP 協議的檔案上傳一樣,要求在請求報文的主體中包含檔案內容,然後儲存到請求 URI 指定的位置。

    但是,鑑於 HTTP 的 PUT 方法自身不帶驗證機制,任何人都可以上傳檔案 , 存在安全性問題,因此一般的 W eb 網站不使用該方法。若配合 W eb 應用程式的驗證機制,或架構設計採用REST(REpresentational State Transfer,表徵狀態轉移)標準的同類 Web 網站,就可能會開放使用 PUT 方法。

  • HEAD 獲得響應首部,HEAD 方法和 GET 方法一樣,只是不返回報文主體部分。用於確認 URI 的有效性及資源更新的日期時間等。

  • DELETE 刪除檔案,DELETE 方法用來刪除檔案,是與 PUT 相反的方法。DELETE 方法按請求 URI 刪除指定的資源。

  • OPTIONS 詢問支援的方法,OPTIONS 方法用來查詢針對請求 URI 指定的資源支援的方法。

  • TRACE 追蹤路徑,TRACE 方法是讓 Web 伺服器端將之前的請求通訊環回給客戶端的方法。

  • CONNECT 要求用隧道協議連線代理,CONNECT 方法要求在與代理伺服器通訊時建立隧道,實現用隧道協議進行 TCP 通訊。主要使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協議把通訊內容加 密後經網路隧道傳輸。

我們一般最常用的方法也就是 GET 方法和 POST 方法,其他方法暫時瞭解即可。下面是 HTTP1.0 和 HTTP1.1 支援的方法清單

HTTP 請求 URL

HTTP 協議使用 URI 定位網際網路上的資源。正是因為 URI 的特定功能,在網際網路上任意位置的資源都能訪問到。URL 帶有請求物件的識別符號。在上面的例子中,瀏覽器正在請求物件 /somedir/page.html 的資源。

我們再通過一個完整的域名解析一下 URL

比如 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument 這個 URL 比較繁瑣了吧,你把這個 URL 搞懂了其他的 URL 也就不成問題了。

首先出場的是 http

http://告訴瀏覽器使用何種協議。對於大部分 Web 資源,通常使用 HTTP 協議或其安全版本,HTTPS 協議。另外,瀏覽器也知道如何處理其他協議。例如, mailto: 協議指示瀏覽器開啟郵件客戶端;ftp:協議指示瀏覽器處理檔案傳輸。

第二個出場的是 主機

www.example.com 既是一個域名,也代表管理該域名的機構。它指示了需要向網路上的哪一臺主機發起請求。當然,也可以直接向主機的 IP address 地址發起請求。但直接使用 IP 地址的場景並不常見。

第三個出場的是

我們前面說到,兩個主機之間要發起 TCP 連線需要兩個條件,主機 + 埠。它表示用於訪問 Web 伺服器上資源的入口。如果訪問的該 Web 伺服器使用HTTP協議的標準埠(HTTP為80,HTTPS為443)授予對其資源的訪問許可權,則通常省略此部分。否則埠就是 URI 必須的部分。

上面是請求 URL 所必須包含的部分,下面就是 URL 具體請求資源路徑

第四個出場的是 路徑

/path/to/myfile.html 是 Web 伺服器上資源的路徑。以埠後面的第一個 / 開始,到 ? 號之前結束,中間的 每一個/ 都代表了層級(上下級)關係。這個 URL 的請求資源是一個 html 頁面。

緊跟著路徑後面的是 查詢引數

?key1=value1&key2=value2 是提供給 Web 伺服器的額外引數。如果是 GET 請求,一般帶有請求 URL 引數,如果是 POST 請求,則不會在路徑後面直接加引數。這些引數是用 & 符號分隔的鍵/值對列表。key1 = value1 是第一對,key2 = value2 是第二對引數

緊跟著引數的是錨點

#SomewhereInTheDocument 是資源本身的某一部分的一個錨點。錨點代表資源內的一種“書籤”,它給予瀏覽器顯示位於該“加書籤”點的內容的指示。 例如,在HTML文件上,瀏覽器將滾動到定義錨點的那個點上;在視訊或音訊文件上,瀏覽器將轉到錨點代表的那個時間。值得注意的是 # 號後面的部分,也稱為片段識別符號,永遠不會與請求一起傳送到伺服器。

更多有關 HTTP1.1 的內容可以參考博主的這三篇博文,我感覺已經把 HTTP 講清楚了

看完這篇HTTP,跟面試官扯皮就沒問題了

你還在為 HTTP 的這些概念頭疼嗎?

震驚 | HTTP 在疫情期間把我嚇得不敢出門了

因特網中的電子郵件

自從有了因特網,電子郵件就在因特網上流行起來。與普通郵件一樣,電子郵件是一種非同步通訊媒介,即人們方便的情況下就可以和他人進行郵件往來,而不必與他人進行溝通後在傳送。現代電子郵件具有許多強大的特性,包括具有附件、超連結、HTML 格式文字和圖片的報文。下面是電子郵件系統的總體概覽

從圖中我們可以看到它有三個主要組成部分:使用者代理(user agent)郵件伺服器(mail server)、和簡單郵件傳輸協議(Simple Mail Transfer Protocol,SMTP)。下面我們就來描述一下郵件收發的過程。

使用者代理允許使用者閱讀、回覆、轉發、儲存和撰寫報文。微軟的 OutlookApple Mail 是電子郵件使用者代理的例子。當用戶編寫完郵件時,他的使用者代理向郵件伺服器傳送郵件,此時使用者傳送的郵件會放在郵件伺服器的外出訊息佇列(Outgoing message queue)中,當接收方使用者想要閱讀郵件時,他的使用者代理直接從外出訊息佇列中去取得該報文。

郵件伺服器構成了整個郵件系統的核心。每個接收方在其中的郵件伺服器上會有一個郵箱(mailbox) 存在。使用者的郵箱管理和維護髮送給他的報文。一個典型的郵件傳送過程是:從傳送方的使用者代理開始,傳輸到傳送方的郵件伺服器,再傳輸到接收方的郵件伺服器,然後在這裡被分發到接收方的郵箱中。用接收方的使用者想要從郵箱中讀取郵件時,他的郵件伺服器會對使用者進行認證。如果傳送方傳送的郵件無法正確交付給接收方的伺服器,那麼傳送方的使用者代理會把郵件儲存在一個報文佇列(message queue)中,並在以後嘗試再次傳送,通常每30分鐘傳送一次,如果一段時間後還發送不成功,伺服器就會刪除報文佇列中的郵件並以電子郵件的方式通知傳送方。

SMTP 是因特網電子郵件中的主要的應用層協議。SMTP 也使用 TCP 作為運輸層協議,保證資料傳輸的可靠性。

SMTP 協議傳輸過程

為了描述 SMTP 的基本操作,我們觀察一下下面這種常見的情景。

我們假設 Alice 想給 Bob 傳送一封簡單的 ASCII 報文

  • Alice 呼叫她的郵件代理程式並提供 Bob 的郵件地址 (例如 [email protected]),編寫郵件報文,然後指示使用者代理髮送該報文
  • Alice 的使用者代理把報文傳送給她的郵件伺服器,在那裡該報文被放在訊息佇列中。
  • 執行在 Alice 的郵件伺服器上的 SMTP 客戶端發現了報文佇列中的郵件,它就建立一個到執行在 Bob 郵件伺服器上的 SMTP 伺服器的 TCP 連線

  • 在經過一些初始化 SMTP 握手後,SMTP 客戶端通過該 TCP 連線傳送 Alice 的郵件。

  • 在 Bob 的郵件伺服器上,SMTP 的服務端接收該郵件,Bob 的郵件伺服器將郵件放在 Bob 的郵箱中
  • 在 Bob 想要看郵件時,他會呼叫使用者代理閱讀該郵件

上面說的郵件其實就是報文,指的就是一系列 ASCII 碼,SMTP 傳輸郵件之前,需要將二進位制多媒體資料編碼為 ASCII 碼進行傳輸。

SMTP 一般不使用中間郵件伺服器傳送郵件,即使這兩個郵件伺服器位於地球的兩端也是這樣的。TCP 連線通常直接連線 Alice 的郵件伺服器和 Bob 的郵件伺服器。

現在你知道了兩臺郵件伺服器郵件傳送的大體過程,那麼,SMTP 是如何將郵件從 Alice 郵件伺服器傳送到 Bob 的郵件伺服器的呢?主要分為下面三個階段

  • 建立連線:在這一階段,SMTP 客戶請求與伺服器的25埠建立一個 TCP 連線。一旦連線建立,SMTP 伺服器和客戶就開始相互通告自己的域名,同時確認對方的域名。
  • 郵件傳送:一旦連線建立後,就開始郵件傳輸。SMTP 依靠 TCP 能夠將郵件準確無誤地傳輸到接收方的郵件伺服器中。SMTP 客戶將郵件的源地址、目的地址和郵件的具體內容傳遞給 SMTP 伺服器,SMTP 伺服器進行相應的響應並接收郵件。
  • 連線釋放:SMTP 客戶發出退出命令,伺服器在處理命令後進行響應,隨後關閉 TCP 連線。

下面我們分析一個實際的 SMTP 郵件傳送過程,以下統稱為SMTP客戶(C)SMTP伺服器(S)。客戶的主機名為 crepes.fr,伺服器的主機名為 hamburger.edu。以 C: 開頭的 ASCII 碼文字就是客戶交給 TCP 套接字的那些行,以 S: 開頭的 ASCII 碼則是伺服器傳送給其 TCP 套接字的那些行。一旦建立了連線,就開始瞭如下過程

S: 220 hamburger.edu
C: HELO crepes.fr
S: 250 Hello crepes.fr, pleased to meet you
C: MAIL FROM: <[email protected]>
S: 250 [email protected] ... Sender ok
C: RCPT TO: <[email protected]>
S: 250 [email protected] ... Recipient ok
C: DATA
S: 354 Enter mail, end with "." on a line by itself
C: Do you like ketchup?
C: How about pickles?
C: .
S: 250 Message accepted for delivery
C: QUIT
S: 221 hamburger.edu closing connection

在上述例子中,客戶從郵件伺服器 crepes.fr 向郵件伺服器 hamburger.edu 傳送了一個報文 (" Do you like ketchup? How about pickles? ") 。作為對話的一部分,該客戶傳送了 5 條命令: HELO(是 HELLO 的縮寫)MAMIL FROMRCPT TODATA 以及 QUIT。這些命令都是自解釋的。

什麼是自解釋,就是不需要再進行解釋了,命令自己就能解釋自己所要表述的功能。

上面是一個簡單的 SMTP 交換過程,包括了連線建立、郵件傳送和連線釋放三個具體過程

首先建立 TCP 連線、SMTP 呼叫 TCP 協議的25號埠監聽連線請求,然後客戶端傳送 HELO 指令用來表明自己是傳送方的身份,然後服務端作出響應。然後,客戶端傳送 MAIL FROM 命令,表明客戶端的郵件地址是 <[email protected]>,伺服器以 OK 作為響應,表明準備接收。客戶端傳送 RCPT TO 表明接收方的電子郵件地址,可以有多個 RCPT 行,即一份郵件可以同時傳送給多個收件人。伺服器端則表示是否願意為收件人接收郵件。協商結束後,客戶端用 DATA 命令傳送資訊,結束標誌是CRLF.CRLF ,也就是 回車換行.回車換行。最後,控制互動的任一端可選擇終止會話,為此它發出一個 QUIT 命令,另一端用命令221響應,表示同意終止連線,雙方將關閉連線。

上述過程中會涉及幾個類似 HTTP 的狀態碼。250 就表示 OK ,類似 HTTP 的 200。在命令成功時,伺服器返回程式碼250,如果失敗則返回程式碼550(命令無法識別)、451(處理時出錯)、452(儲存空間不夠)、421(伺服器不可用)等,354則表示開始資訊輸入。

SMTP 的報文會有侷限性,SMTP 的侷限性表現在只能傳送 ASCII 碼格式的報文,不支援中文、法文、德文等,它也不支援語音、視訊的資料。通過 MIME協議,對 SMTP 補充。MIME 使用網路虛擬終端(NVT)標準,允許非ASCII碼資料通過SMTP傳輸。

SMTP 與 HTTP 的對比

HTTP 是我們學習的第一個應用層協議,SMTP 是我們學習的第二個應用層協議,那麼我們就對這兩個協議進行比對。

這兩個協議都用於從一臺主機向另一臺主機傳送檔案:HTTP 從 Web 伺服器向 Web 客戶端(通常是瀏覽器)傳送檔案,SMTP 是從一個郵件伺服器向另一個郵件伺服器傳送檔案(即電子郵件報文)。

這兩個協議也會有幾個重要的區別

  • 首先,HTTP 是一個 拉協議(pull protocol),客戶端傳送請求,請求獲取服務端的資源,然後服務端進行響應,把需要下載的檔案傳輸給客戶端;而 SMTP 是一個 推協議(push protocol),SMTP 的客戶端會主動把郵件推送給 SMTP 的服務端。
  • 第二個區別是,SMTP 要求每個報文都採用 7 位元的 ASCII 碼格式,如果某報文包含了非 7 位元的 ASCII 自負或二進位制資料,則該報文必須按照7位元 ASCII 碼進行編碼。HTTP 資料則不受這種限制。
  • 第三個區別是如何處理一個既包含文字又包含圖形的文件,HTTP 把每個物件封裝到它自己的 HTTP 響應報文中,而 SMTP 則把所有報文物件放在一個報文之中。

DNS 因特網目錄服務協議

試想一個問題,我們人類可以有多少種識別自己的方式?可以通過身份證來識別,可以通過社保卡號來識別,也可以通過駕駛證來識別,儘管我們有多種識別方式,但在特定的環境下,某種識別方法可能比另一種方法更為適合。因特網上的主機和人類一樣,可以使用多種識別方式進行標識。網際網路上主機的一種標識方法是使用它的 主機名(hostname) ,如 www.facebook.com、 www.google.com 等。但是這是我們人類的記憶方式,路由器不會這麼理解,路由器喜歡定長的、有層次結構的 IP地址,so,還記得 IP 是什麼嗎?

IP 地址現在簡單表述一下,就是一個由 4 位元組組成,並有著嚴格的層次結構。例如 121.7.106.83 這樣一個 IP 地址,其中的每個位元組都可以用 . 進行分割,表示了 0 - 255 的十進位制數字。(具體的 IP 我們會在後面討論)

然而,路由器喜歡的是 IP 地址進行解析,我們人類卻便於記憶的是網址,那麼路由器如何把 IP 地址解析為我們熟悉的網址地址呢?這時候就需要 DNS 出現了。

DNS 的全稱是 Domain Name System,DNS ,它是一個由分層的 DNS 伺服器(DNS server)實現的分散式資料庫;它還是一個使得主機能夠查詢分散式資料庫的應用層協議。DNS 伺服器通常是執行 BIND(Berkeley Internet Name Domain) 軟體的 UNIX 機器。DNS 協議執行在 UDP 之上,使用 53 埠。

DNS 基本概述

與 HTTP、FTP 和 SMTP 一樣,DNS 協議也是應用層的協議,DNS 使用客戶-伺服器模式執行在通訊的端系統之間,在通訊的端系統之間通過下面的端到端運輸協議來傳送 DNS 報文。但是 DNS 不是一個直接和使用者打交道的應用。DNS 是為因特網上的使用者應用程式以及其他軟體提供一種核心功能。

DNS 通常不是一門獨立的協議,它通常為其他應用層協議所使用,這些協議包括 HTTP、SMTP 和 FTP,將使用者提供的主機名解析為 IP 地址。

下面根據一個示例來描述一下這個 DNS 解析過程,這個和你輸入網址後,瀏覽器做了什麼操作有異曲同工之處

你在瀏覽器鍵入 www.someschool.edu/index.html 時會發生什麼現象?為了使使用者主機能夠將一個 HTTP 請求報文傳送到 Web 伺服器 www.someschool.edu ,會經歷如下操作

  • 同一臺使用者主機上執行著 DNS 應用的客戶端
  • 瀏覽器從上述 URL 中抽取出主機名 www.someschool.edu ,並將這臺主機名傳給 DNS 應用的客戶端
  • DNS 客戶向 DNS 伺服器傳送一個包含主機名的請求。
  • DNS 客戶最終會收到一份回答報文,其中包含該目標主機的 IP 地址
  • 一旦瀏覽器收到目標主機的 IP 地址後,它就能夠向位於該 IP 地址 80 埠的 HTTP 伺服器程序發起一個 TCP 連線。

除了提供 IP 地址到主機名的轉換,DNS 還提供了下面幾種重要的服務

  • 主機別名(host aliasing),有著複雜的主機名的主機能夠擁有一個或多個其他別名,比如說一臺名為 relay1.west-coast.enterprise.com 的主機,同時會擁有 enterprise.com 和 www.enterprise.com 的兩個主機別名,在這種情況下,relay1.west-coast.enterprise.com 也稱為 規範主機名,而主機別名要比規範主機名更加容易記憶。應用程式可以呼叫 DNS 來獲得主機別名對應的規範主機名以及主機的 IP地址。
  • 郵件伺服器別名(mail server aliasing),同樣的,電子郵件的應用程式也可以呼叫 DNS 對提供的主機名進行解析。
  • 負載分配(load distribution),DNS 也用於冗餘的伺服器之間進行負載分配。繁忙的站點例如 cnn.com 被冗餘分佈在多臺伺服器上,每臺伺服器執行在不同的端系統之間,每個都有著不同的 IP 地址。由於這些冗餘的 Web 伺服器,一個 IP 地址集合因此與同一個規範主機名聯絡。DNS 資料庫中儲存著這些 IP 地址的集合。由於客戶端每次都會發起 HTTP 請求,所以 DNS 就會在所有這些冗餘的 Web 伺服器之間迴圈分配了負載。

DNS 工作概述

DNS 是一個複雜的系統,我們在這裡只是就其執行的主要方面進行學習,下面給出一個 DNS 工作過程的總體概述

假設執行在使用者主機上的某些應用程式(如 Web 瀏覽器或郵件閱讀器) 需要將主機名轉換為 IP 地址。這些應用程式將呼叫 DNS 的客戶端,並指明需要被轉換的主機名。使用者主機上的 DNS 收到後,會使用 UDP 通過 53 埠向網路上傳送一個 DNS 查詢報文,經過一段時間後,使用者主機上的 DNS 會收到一個主機名對應的 DNS 回答報文。因此,從使用者主機的角度來看,DNS 就像是一個黑盒子,其內部的操作你無法看到。但是實際上,實現 DNS 這個服務的黑盒子非常複雜,它由分佈於全球的大量 DNS 伺服器以及定義了 DNS 伺服器與查詢主機通訊方式的應用層協議組成。

DNS 最早的一種簡單設計只是在因特網上使用一個 DNS 伺服器。該伺服器會包含所有的對映。這是一種集中式的設計,這種設計並不適用於當今的網際網路,因為網際網路有著數量巨大並且持續增長的主機,這種集中式的設計會存在以下幾個問題

  • 單點故障(a single point of failure),如果 DNS 伺服器崩潰,那麼整個網路隨之癱瘓。
  • 通訊容量(traaffic volume),單個 DNS 伺服器不得不處理所有的 DNS 查詢,這種查詢級別可能是上百萬上千萬級
  • 遠距離集中式資料庫(distant centralized database),單個 DNS 伺服器不可能 鄰近 所有的使用者,假設在美國的 DNS 伺服器不可能臨近讓澳大利亞的查詢使用,其中查詢請求勢必會經過低速和擁堵的鏈路,造成嚴重的時延。
  • 維護(maintenance),維護成本巨大,而且還需要頻繁更新。

所以 DNS 不可能集中式設計,它完全沒有可擴充套件能力,因此採用分散式設計,所以這種設計的特點如下

分散式、層次資料庫

首先分散式設計首先解決的問題就是 DNS 伺服器的擴充套件性問題,因此 DNS 使用了大量的 DNS 伺服器,它們的組織模式一般是層次方式,並且分佈在全世界範圍內。沒有一臺 DNS 伺服器能夠擁有因特網上所有主機的對映。相反,這些對映分佈在所有的 DNS 伺服器上。

大致來說有三種 DNS 伺服器:根 DNS 伺服器頂級域(Top-Level Domain, TLD) DNS 伺服器權威 DNS 伺服器 。這些伺服器的層次模型如下圖所示

假設現在一個 DNS 客戶端想要知道 www.amazon.com 的 IP 地址,那麼上面的域名伺服器是如何解析的呢?首先,客戶端會先根伺服器之一進行關聯,它將返回頂級域名 com 的 TLD 伺服器的 IP 地址。該客戶則與這些 TLD 伺服器之一聯絡,它將為 amazon.com 返回權威伺服器的 IP 地址。最後,該客戶與 amazom.com 權威伺服器之一聯絡,它為 www.amazom.com 返回其 IP 地址。

我們現在來討論一下上面域名伺服器的層次系統

  • 根 DNS 伺服器 ,有 400 多個根域名伺服器遍及全世界,這些根域名伺服器由 13 個不同的組織管理。根域名伺服器的清單和組織機構可以在 https://root-servers.org/ 中找到,根域名伺服器提供 TLD 伺服器的 IP 地址。
  • 頂級域 DNS 伺服器,對於每個頂級域名比如 com、org、net、edu 和 gov 和所有的國家級域名 uk、fr、ca 和 jp 都有 TLD 伺服器或伺服器叢集。所有的頂級域列表參見 https://tld-list.com/ 。TDL 伺服器提供了權威 DNS 伺服器的 IP 地址。
  • 權威 DNS 伺服器,在因特網上具有公共可訪問的主機,如 Web 伺服器和郵件伺服器,這些主機的組織機構必須提供可供訪問的 DNS 記錄,這些記錄將這些主機的名字對映為 IP 地址。一個組織機構的權威 DNS 伺服器收藏了這些 DNS 記錄。

一般域名伺服器的層次結構主要是以上三種,除此之外,還有另一類重要的 DNS 伺服器,它是 本地 DNS 伺服器(local DNS server)。嚴格來說,本地 DNS 伺服器並不屬於上述層次結構,但是本地 DNS 伺服器又是至關重要的。每個 ISP(Internet Service Provider) 比如居民區的 ISP 或者一個機構的 ISP 都有一臺本地 DNS 伺服器。當主機和 ISP 進行連線時,該 ISP 會提供一臺主機的 IP 地址,該主機會具有一臺或多臺其本地 DNS 伺服器的 IP地址。通過訪問網路連線,使用者能夠容易的確定 DNS 伺服器的 IP地址。當主機發出 DNS 請求後,該請求被髮往本地 DNS 伺服器,它起著代理的作用,並將該請求轉發到 DNS 伺服器層次系統中。

DNS 快取

DNS 快取(DNS caching) 有時也叫做 DNS 解析器快取,它是由作業系統維護的臨時資料庫,它包含有最近的網站和其他 Internet 域的訪問記錄。也就是說, DNS 快取只是計算機為了滿足快速的響應速度而把已載入過的資源快取起來,再次訪問時可以直接快速引用的一項技術和手段。那麼 DNS 的快取是如何工作的呢?

DNS 快取的工作流程

在瀏覽器向外部發出請求之前,計算機會攔截每個請求並在 DNS 快取資料庫中查詢域名,該資料庫包含有最近的域名列表,以及 DNS 首次發出請求時 DNS 為它們計算的地址。

DNS 記錄和報文

共同實現 DNS 分散式資料庫的所有 DNS 伺服器儲存了資源記錄(Resource Record, RR),RR 提供了主機名到 IP 地址的對映。每個 DNS 回答報文中會包含一條或多條資源記錄。RR 記錄用於回覆客戶端查詢。

資源記錄是一個包含了下列欄位的 4 元組

(Name, Value, Type, TTL)

RR 會有不同的型別,下面是不同型別的 RR 彙總表

DNS RR 型別 解釋
A 記錄 IPv4 主機記錄,用於將域名對映到 IPv4 地址
AAAA 記錄 IPv6 主機記錄,用於將域名對映到 IPv6 地址
CNAME 記錄 別名記錄,用於對映 DNS 域名的別名
MX 記錄 郵件交換器,用於將 DNS 域名對映到郵件伺服器
PTR 記錄 指標,用於反向查詢(IP地址到域名解析)
SRV 記錄 SRV記錄,用於對映可用服務。

DNS 報文

DNS 有兩種報文,一種是查詢報文,一種是響應報文,並且這兩種報文有著相同的格式,下面是 DNS 的報文格式

下面對報文格式進行解釋

  • 前 12 個報文是 首部區域,也就是說首部區域有 12 個位元組,第一個欄位(識別符號)是一個 16 位元的數,用於標示該查詢。這個識別符號會被複制到對查詢的回答報文中,以便讓客戶用它來匹配發送的請求和接受到的回答。 標誌欄位含有若干標誌,標誌欄位表示為 1 位元,它用於指出報文是 0-查詢報文還是 1-響應報文。

  • 問題區域包含著正在進行的查詢資訊。這個區域包括:1) 名字欄位,包含正在被查詢的主機名字;2) 型別欄位,指出有關該名字的正被詢問的問題型別,例如主機地址是與一個名字相關聯(型別 A)還是與某個名字的郵件伺服器相關聯(型別 MX)。
  • 在來自 DNS 伺服器的回答中,回答區域包含了對最初請求的名字的資源記錄。上面說過 DNS RR記錄是個四元組,而且元組中的 Type 會有不同的型別。在回答報文的回答區域中可以包含多條 RR,因此一個主機名能夠有多個 IP 地址。
  • 權威區域 包含了其他權威伺服器的記錄
  • 附加區域 包含了其他有幫助的記錄。

關於具體 DNS 記錄的詳細介紹我會出一篇文章專門探討。

P2P 檔案分發

我們上面探討的協議 HTTP、SMTP、DNS 都採用了客戶-伺服器 模式,這種模式會極大依賴總是開啟的基礎設施伺服器。而 P2P 是客戶端與客戶端模式,對總是開啟的基礎設施伺服器有最小的依賴。

P2P 的全稱是 Peer-to-peer, P2P ,是一種分散式體系結構的計算機網路。在 P2P 體系中,所有的計算機和裝置都被稱為對等體,他們互相交換工作。對等網路中的每個對等方都等於其他對等方。網路中沒有特權對等體,也沒有主管理員裝置。

從某種意義上說,對等網路是計算機世界中最平等的網路。每個對等方都相等,並且每個對等方具有與其他對等方相同的權利和義務。對等體同時是客戶端和伺服器。

實際上,對等網路中可用的每個資源都是在對等之間共享的,而無需任何中央伺服器。P2P 網路中的共享資源可以是諸如處理器使用率,磁碟儲存容量或網路頻寬等。

P2P 用來做什麼

P2P 的主要目標是共享資源並幫助計算機和裝置協同工作,提供特定服務或執行特定任務。如前面說到的,P2P 用於共享各種計算資源,例如網路頻寬或磁碟儲存空間。 但是,對等網路最常見的例子是 Internet 上的檔案共享。 對等網路非常適合檔案共享,因為它們允許連線到它們計算機等同時接收檔案和傳送檔案。

BitTorrent 是 P2P 使用的主要協議。

P2P 網路的作用

P2P 網路具有一些使它們有用的特徵

  • 很難完全掉線,即使其中的一個對等方掉線,其他對等方仍在執行並進行通訊。 為了使 P2P(對等)網路停止工作,你必須關閉所有對等網路。對等網路具有很強的可擴充套件性。 新增新的對等節點很容易,因為你無需在中央伺服器上進行任何中央配置。
  • 當涉及到檔案共享時,對等網路越大,速度越快。 在 P2P 網路中的許多對等點上儲存相同的檔案意味著當某人需要下載檔案時,該檔案會同時從多個位置下載。

視訊流和內容分發網

因特網視訊

在流式儲存視訊應用中,最基礎的媒體是預先錄製的視訊例如電影、電視節目、錄製好的體育事件或者使用者生成的視訊。這些預先錄製好的視訊會放置在伺服器上,使用者按需向伺服器傳送請求來觀看視訊。許多因特網公司現在提供流式視訊,這些公司包括 Netflix、YouTube 、亞馬遜和優酷等。

視訊式一系列的影象,通常會以一種恆定的速率(如每秒 24 或 30 張影象)來展現。一幅未壓縮、數字編碼的影象由畫素陣列組成,其中每個畫素又一些位元編碼來表示亮度和顏色。視訊的一個重要特徵是它能夠被壓縮、因而可用位元率來權衡視訊質量。

HTTP 流和 DASH

在 HTTP 流中,視訊只是儲存在 HTTP 伺服器中的一個檔案,每個檔案有特定的 URL。當用戶想要看視訊時,客戶與伺服器建立一個 TCP 連線併發送該 URL 的 HTTP GET 請求。伺服器則以底層網路協議和流量條件允許的儘可能快的速率,在一個 HTTP 響應中傳送該檔案視訊。

儘管 HTTP 流在實踐中已經得到廣泛部署,但是它由嚴重缺陷,即所有客戶接收到相同編碼的視訊,但是對於客戶而言,頻寬時動態變化的,在不同的時間,頻寬大小有很大不同。這種情況導致了一種新型 HTTP 流的研發,它常常被稱為 經 HTTP 的動態適應性流(Dynamic Adaptive Streaming over HTTP, DASH)。在 DASH 中,視訊編碼為幾個不同的版本,每個版本對應不同的位元率。

DASH 允許客戶使用不同的乙太網接入速率流失播放具有不同編碼速率的視訊。使用 3G 連線的客戶能夠接受一個低位元率的版本,使用光纖能夠接受高位元率的版本。

使用 DASH 後,每個視訊版本儲存在 HTTP 中,每個版本都有一個不同的 URL。HTTP 伺服器也會有一個 告示檔案(manifest file),為每個版本提供了一個 URL 及其位元率。

內容分發網

現如今,許多因特網視訊公司日復一日地向數以百萬計的使用者按需分發每秒數兆位元的流。對於一個因特網視訊公司,或許提供流式視訊服務最為直接的方法是建立一個單一的超大規模的資料中心。在資料中心內部儲存所有視訊,然後把視訊返回到全世界範圍內的客戶。這種方式存在三個問題

  • 如果客戶遠離資料中心,伺服器到客戶的分組將跨越許多通訊鏈路並可能通過很多 ISP,造成通訊延遲

  • 流式視訊可能經過相同的鏈路傳送了許多次,造成頻寬和資源浪費。
  • 單點問題,如果單一結點故障,這可能是災難性的。

為了應對向分佈於去啊按時接的使用者分發巨量視訊資料的挑戰,幾乎所有主要的視訊流公司都利用 內容分發網(Content Distribution Network, CDN)。 CDN 管理分佈在多個地理位置上的伺服器,在它的伺服器上儲存視訊副本,並且所有試圖將每個使用者請求定向到一個提供最好使用者體驗的 CDN 位置。那麼伺服器如何選址呢?事實上有兩種伺服器安置原則

  • 深入,它的主要目標是靠近使用者,通過減少端使用者和 CDN 叢集之間鏈路和路由器的數量,從而改善了使用者感受的時延和吞吐量。
  • 邀請做客,這個原則是通過在少量(例如 10 個)關鍵位置建造大叢集來邀請 ISP 來做客,與深入設計原則相比,邀請做客設計通常產生較低的維護和管理開銷。

CDN 可以是專用 CDN(private CDN), 即它由內容提供商自己所擁有;另一種 CDN 是 第三方 CDN(third-party CDN),它代表多個內容提供商分發內容。

CDN 分發過程

上面我們探討了一下 CDN 的選址過程,那麼 CDN 是如何工作的呢?

當用戶主機中的一個瀏覽器指令檢索一個特定的視訊(由 URL 標識)時,CDN 必須能夠截獲請求,來進行下面的操作

  • 確定此時適用於該客戶的 CDN 伺服器叢集
  • 將客戶的請求重定向到叢集中的某臺伺服器上

大多數 CDN 利用 DNS 協議來截獲和重定向請求。

下面是 CDN 的具體工作流程

假設一個內容提供商 NetCinema ,僱用了第三方 CDN 公司 KingCDN 來向它的客戶分發視訊。在 NetCinema 的 Web 網頁上,它的每個視訊都被指派了一個 URL,該 URL 包括了字串 video 以及視訊本身的識別符號。下面要訪問 http://video.netcinema.com/6Y7B23V ,它的工作過程如下

  1. 使用者訪問位於 NetCinema 的 Web 網頁
  2. 當用戶點選連結 http://video.netcinema.com/6Y7B23V 時,該使用者主機發送了對於 video.netcinema.com 的 DNS 請求
  3. 使用者本地 DNS 伺服器(LDNS, Local DNS) 將該 DNS 請求中繼到一臺用於 NetCinema 的權威 DNS 伺服器,該伺服器觀察到主機名 video.netcinema.com 中的字串 video。為了將該 DNS 請求移交給 KingCDN,NetCinema 權威 DNS 伺服器並不返回一個 IP 地址,而是向 LDNS 返回一個 KingCDN 域的主機名,如 a1105.kingcdn.com
  4. 從此時起,DNS 請求就會進入 KingCDN 專用 DNS 基礎設施,使用者的 LDNS 則傳送第二個請求,此時是對 a1105.kingcdn.com 的 DNS 請求,KingCDN 的 DNS 系統最終向 LDNS 返回 KingCDN 內容伺服器的 IP 地址。所以正是這裡,在 KingCDN 的 DNS 系統中,指定了 CDN 伺服器,客戶將能夠從這臺伺服器接收它的內容
  5. LDNS 向用戶主機轉發內容服務 CDN 節點的 IP 地址
  6. 一旦客戶收到 KingCDN 內容伺服器的 IP 地址,它與具有該 IP 地址的伺服器建立一條 TCP 連線,並且發出對該視訊的 HTTP GET 請求。如果使用了 DASH,伺服器將首先向客戶傳送具有 URL 列表的告示檔案,每個 URL 對應視訊的每個版本,並且客戶將動態的選擇來自不同版本的塊。

CDN 的叢集選擇策略

任何 CDN 的部署,其核心是 叢集選擇策略(cluster selection strategy), 即動態的將客戶定向到 CDN 中某個伺服器叢集或資料中心的機制