第14講 | HTTP協議:看個新聞原來這麼麻煩

sir發表於2021-05-31

第14講 | HTTP協議:看個新聞原來這麼麻煩

http://www.163.com 是個 URL,叫作統一資源定位符。

  之所以叫統一,是因為它是有格式的。HTTP 稱為協議,www.163.com 是一個域名,表示網際網路上的一個位置。有的 URL 會有更詳細的位置標識,例如 http://www.163.com/index.html 。正是因為這個東西是統一的,所以當你把這樣一個字串輸入到瀏覽器的框裡的時候,瀏覽器才知道如何進行統一處理。

HTTP 請求的準備

  瀏覽器會將 www.163.com 這個域名傳送給 DNS 伺服器,讓它解析為 IP 地址。有關 DNS 的過程,其實非常複雜,這個在後面專門介紹 DNS 的時候,我會詳細描述,這裡我們先不管,反正它會被解析成為 IP 地址。那接下來是傳送 HTTP 請求嗎?

  不是的,HTTP 是基於 TCP 協議的,當然是要先建立 TCP 連線了,怎麼建立呢?還記得第 11 節講過的三次握手嗎?目前使用的 HTTP 協議大部分都是 1.1。在 1.1 的協議裡面,預設是開啟了 Keep-Alive 的,這樣建立的 TCP 連線,就可以在多次請求中複用。

  學習了 TCP 之後,你應該知道,TCP 的三次握手和四次揮手,還是挺費勁的。如果好不容易建立了連線,然後就做了一點兒事情就結束了,有點兒浪費人力和物力。

  瀏覽器訪問服務端之後, 一個http請求的底層是tcp連線, tcp連線要經過三次握手之後,開始傳輸資料, 而且因為http設定了keep-alive,所以單次http請求完成之後這條tcp連線並不會斷開, 而是可以讓下一次http請求直接使用.當然keep-alive肯定也有timeout, 超時關閉.

 

HTTP 請求的構建

建立了連線以後,瀏覽器就要傳送 HTTP 的請求。請求的格式就像這樣。

第14講 | HTTP協議:看個新聞原來這麼麻煩

HTTP 的報文大概分為三大部分。

  第一部分是請求行,

  第二部分是請求的首部,

  第三部分才是請求的正文實體。

第一部分:請求行在請求行中,URL 就是 http://www.163.com ,版本為 HTTP 1.1。

  這裡要說一下的,就是方法。方法有幾種型別。對於訪問網頁來講,

  最常用的型別就是 GET。顧名思義,GET 就是去伺服器獲取一些資源。對於訪問網頁來講,要獲取的資源往往是一個頁面。其實也有很多其他的格式,比如說返回一個 JSON 字串,到底要返回什麼,是由伺服器端的實現決定的。

  例如,在雲端計算中,如果我們的伺服器端要提供一個基於 HTTP 協議的 API,獲取所有云主機的列表,這就會使用 GET 方法得到,返回的可能是一個 JSON 字串。字串裡面是一個列表,列表裡面是一項的雲主機的資訊。

  另外一種型別叫做 POST。它需要主動告訴服務端一些資訊,而非獲取。要告訴服務端什麼呢?一般會放在正文裡面。正文可以有各種各樣的格式。常見的格式也是 JSON。

  例如,我們下一節要講的支付場景,客戶端就需要把“我是誰?我要支付多少?我要買啥?”告訴伺服器,這就需要通過 POST 方法。再如,在雲端計算裡,如果我們的伺服器端,要提供一個基於 HTTP 協議的建立雲主機的 API,也會用到 POST 方法。

  這個時候往往需要將“我要建立多大的雲主機?多少 CPU 多少記憶體?多大硬碟?”這些資訊放在 JSON 字串裡面,通過 POST 的方法告訴伺服器端。

  還有一種型別叫 PUT,就是向指定資源位置上傳最新內容。但是,HTTP 的伺服器往往是不允許上傳檔案的,所以 PUT 和 POST 就都變成了要傳給伺服器東西的方法。

  在實際使用過程中,這兩者還會有稍許的區別。POST 往往是用來建立一個資源的,而 PUT 往往是用來修改一個資源的。  

  例如,雲主機已經建立好了,我想對這個雲主機打一個標籤,說明這個雲主機是生產環境的,另外一個雲主機是測試環境的。那怎麼修改這個標籤呢?往往就是用 PUT 方法。再有一種常見的就是 DELETE。這個顧名思義就是用來刪除資源的。例如,我們要刪除一個雲主機,就會呼叫 DELETE 方法。

 

第二部分:首部欄位

  請求行下面就是我們的首部欄位。

  首部是 key value,通過冒號分隔。這裡面,往往儲存了一些非常重要的欄位。

例如,Accept-Charset,表示客戶端可以接受的字符集。防止傳過來的是另外的字符集,從而導致出現亂碼。

再如,Content-Type 是指正文的格式。例如,我們進行 POST 的請求,如果正文是 JSON,那麼我們就應該將這個值設定為 JSON。這裡需要重點說一下的就是快取。為啥要使用快取呢?那是因為一個非常大的頁面有很多東西。

例如,我瀏覽一個商品的詳情,裡面有這個商品的價格、庫存、展示圖片、使用手冊等等。商品的展示圖片會保持較長時間不變,而庫存會根據使用者購買的情況經常改變。如果圖片非常大,而庫存數非常小,如果我們每次要更新資料的時候都要重新整理整個頁面,對於伺服器的壓力就會很大。

  對於這種高併發場景下的系統,在真正的業務邏輯之前,都需要有個接入層,將這些靜態資源的請求攔在最外面。

 

這個架構的圖就像這樣。

第14講 | HTTP協議:看個新聞原來這麼麻煩

其中 DNS、CDN 我在後面的章節會講。和這一節關係比較大的就是 Nginx 這一層,它如何處理 HTTP 協議呢?對於靜態資源,有 Vanish 快取層。當快取過期的時候,才會訪問真正的 Tomcat 應用叢集。

 

在 HTTP 頭裡面,Cache-control 是用來控制快取的。當客戶端傳送的請求中包含 max-age 指令時,如果判定快取層中,資源的快取時間數值比指定時間的數值小,那麼客戶端可以接受快取的資源;當指定 max-age 值為 0,那麼快取層通常需要將請求轉發給應用叢集。

  另外,If-Modified-Since 也是一個關於快取的。也就是說,如果伺服器的資源在某個時間之後更新了,那麼客戶端就應該下載最新的資源;如果沒有更新,服務端會返回“304 Not Modified”的響應,那客戶端就不用下載了,也會節省頻寬。到此為止,我們僅僅是拼湊起了 HTTP 請求的報文格式,接下來,瀏覽器會把它交給下一層傳輸層。怎麼交給傳輸層呢?其實也無非是用 Socket 這些東西,只不過用的瀏覽器裡,這些程式不需要你自己寫,有人已經幫你寫好了。

 

HTTP 請求的傳送

HTTP 協議是基於 TCP 協議的,所以它使用面向連線的方式傳送請求,通過 stream 二進位制流的方式傳給對方。當然,到了 TCP 層,它會把二進位制流變成一個個報文段傳送給伺服器。

  在傳送給每個報文段的時候,都需要對方有一個回應 ACK,來保證報文可靠地到達了對方。如果沒有回應,那麼 TCP 這一層會進行重新傳輸,直到可以到達。同一個包有可能被傳了好多次,但是 HTTP 這一層不需要知道這一點,因為是 TCP 這一層在埋頭苦幹。

TP 請求的傳送HTTP 協議是基於 TCP 協議的,所以它使用面向連線的方式傳送請求,通過 stream 二進位制流的方式傳給對方。當然,到了 TCP 層,它會把二進位制流變成一個個報文段傳送給伺服器。在傳送給每個報文段的時候,都需要對方有一個回應 ACK,來保證報文可靠地到達了對方。如果沒有回應,那麼 TCP 這一層會進行重新傳輸,直到可以到達。同一個包有可能被傳了好多次,但是 HTTP 這一層不需要知道這一點,因為是 TCP 這一層在埋頭苦幹。TCP 層傳送每一個報文的時候,都需要加上自己的地址(即源地址)和它想要去的地方(即目標地址),將這兩個資訊放到 IP 頭裡面,交給 IP 層進行傳輸。IP 層需要檢視目標地址和自己是否是在同一個區域網。如果是,就傳送 ARP 協議來請求這個目標地址對應的 MAC 地址,然後將源 MAC 和目標 MAC 放入 MAC 頭,傳送出去即可;如果不在同一個區域網,就需要傳送到閘道器,還要需要傳送 ARP 協議,來獲取閘道器的 MAC 地址,然後將源 MAC 和閘道器 MAC 放入 MAC 頭,傳送出去。閘道器收到包發現 MAC 符合,取出目標 IP 地址,根據路由協議找到下一跳的路由器,獲取下一跳路由器的 MAC 地址,將包發給下一跳路由器。這樣路由器一跳一跳終於到達目標的區域網。這個時候,最後一跳的路由器能夠發現,目標地址就在自己的某一個出口的區域網上。於是,在這個區域網上傳送 ARP,獲得這個目標地址的 MAC 地址,將包發出去。目標的機器發現 MAC 地址符合,就將包收起來;發現 IP 地址符合,根據 IP 頭中協議項,知道自己上一層是 TCP 協議,於是解析 TCP 的頭,裡面有序列號,需要看一看這個序列包是不是我要的,如果是就放入快取中然後返回一個 ACK,如果不是就丟棄。TCP 頭裡面還有埠號,HTTP 的伺服器正在監聽這個埠號。於是,目標機器自然知道是 HTTP 伺服器這個程式想要這個包,於是將包發給 HTTP 伺服器。HTTP 伺服器的程式看到,原來這個請求是要訪問一個網頁,於是就把這個網頁發給客戶端。HTTP 返回的構建HTTP 的返回報文也是有一定格式的。這也是基於 HTTP 1.1 的。狀態碼會反映 HTTP 請求的結果。“200”意味著大吉大利;而我們最不想見的,就是“404”,也就是“服務端無法響應這個請求”

 

  TCP 層傳送每一個報文的時候,都需要加上自己的地址(即源地址)和它想要去的地方(即目標地址),將這兩個資訊放到 IP 頭裡面,交給 IP 層進行傳輸。

  IP 層需要檢視目標地址和自己是否是在同一個區域網。如果是,就傳送 ARP 協議來請求這個目標地址對應的 MAC 地址,然後將源 MAC 和目標 MAC 放入 MAC 頭,傳送出去即可;如果不在同一個區域網,就需要傳送到閘道器,還要需要傳送 ARP 協議,來獲取閘道器的 MAC 地址,然後將源 MAC 和閘道器 MAC 放入 MAC 頭,傳送出去。

  閘道器收到包發現 MAC 符合,取出目標 IP 地址,根據路由協議找到下一跳的路由器,獲取下一跳路由器的 MAC 地址,將包發給下一跳路由器。

  這樣路由器一跳一跳終於到達目標的區域網。這個時候,最後一跳的路由器能夠發現,目標地址就在自己的某一個出口的區域網上。於是,在這個區域網上傳送 ARP,獲得這個目標地址的 MAC 地址,將包發出去。

  目標的機器發現 MAC 地址符合,就將包收起來;發現 IP 地址符合,根據 IP 頭中協議項,知道自己上一層是 TCP 協議,於是解析 TCP 的頭,裡面有序列號,需要看一看這個序列包是不是我要的,如果是就放入快取中然後返回一個 ACK,如果不是就丟棄。

  TCP 頭裡面還有埠號,HTTP 的伺服器正在監聽這個埠號。於是,目標機器自然知道是 HTTP 伺服器這個程式想要這個包,於是將包發給 HTTP 伺服器。HTTP 伺服器的程式看到,原來這個請求是要訪問一個網頁,於是就把這個網頁發給客戶端。

 

HTTP 返回的構建

HTTP 的返回報文也是有一定格式的。這也是基於 HTTP 1.1 的。

第14講 | HTTP協議:看個新聞原來這麼麻煩

狀態碼會反映 HTTP 請求的結果。

  “200”意味著大吉大利;而我們最不想見的,就是“404”,也就是“服務端無法響應這個請求”。然後,短語會大概說一下原因。

接下來是返回首部的 key value。

  這裡面,Retry-After 表示,告訴客戶端應該在多長時間以後再次嘗試一下。“503 錯誤”是說“服務暫時不再和這個值配合使用”。

在返回的頭部裡面也會有 Content-Type,表示返回的是 HTML,還是 JSON。

  構造好了返回的 HTTP 報文,接下來就是把這個報文傳送出去。還是交給 Socket 去傳送,還是交給 TCP 層,讓 TCP 層將返回的 HTML,也分成一個個小的段,並且保證每個段都可靠到達。

  這些段加上 TCP 頭後會交給 IP 層,然後把剛才的傳送過程反向走一遍。雖然兩次不一定走相同的路徑,但是邏輯過程是一樣的,一直到達客戶端。

  客戶端發現 MAC 地址符合、IP 地址符合,於是就會交給 TCP 層。根據序列號看是不是自己要的報文段,如果是,則會根據 TCP 頭中的埠號,發給相應的程式。這個程式就是瀏覽器,瀏覽器作為客戶端也在監聽某個埠。

  當瀏覽器拿到了 HTTP 的報文。發現返回“200”,一切正常,於是就從正文中將 HTML 拿出來。HTML 是一個標準的網頁格式。瀏覽器只要根據這個格式,展示出一個絢麗多彩的網頁。

  這就是一個正常的 HTTP 請求和返回的完整過程。

 

HTTP 2.0

當然 HTTP 協議也在不斷的進化過程中,在 HTTP1.1 基礎上便有了 HTTP 2.0。

HTTP協議的進化史: 1991年是HTTP0.9。 1996年是HTTP1.0。 1999年是HTTP1.1。 2015年是HTTP2。

HTTP 1.1 在應用層以純文字的形式進行通訊。每次通訊都要帶完整的 HTTP 的頭,而且不考慮 pipeline 模式的話,每次的過程總是像上面描述的那樣一去一回。這樣在實時性、併發性上都存在問題。

 

HTTP1.x的缺點:

   純文字通訊,每次通訊都要帶完整的HTTP頭部。如果不考慮http1.1的pipeline特性。TCP長連線複用是: 一個請求響應完畢後,下一個請求才能傳送,如果請求阻塞了,後面的請求都會受影響。(請求-響應、請求-響應 序列方式使用TCP長連線) 考慮pipeline的TCP長連線複用是: 一個請求傳送完畢後,無需等待響應,便可傳送下一個請求。但是服務端響應的時候只能按照客戶端傳送請求的順序進行響應,如果第一個請求處理特別慢,後面的請求即使處理完畢,也要等著,這就是著名的線頭阻塞問題。 (請求1-請求2-請求3,響應1-響應2-響應3,半並行化使用TCP長連線,如果響應1阻塞,響應2、響應3即使完成了,也不能在TCP連線上傳輸,要等待響應1的完成,響應1傳輸完了,響應2,響應3才能開始傳輸,這就是pipeline特性的線頭阻塞問題) HTTP1.0每有一個請求建立一個TCP連線,三次握手耗時,TCP慢啟動耗時,HTTP1.0的實時性可見一般。更別提併發性了。 HTTP1.1可以建立TCP長連線複用。實時性相比於HTTP1.0有所提高,但是仍然會出現前一個請求阻塞,後一個請求無法使用TCP連線的情況。如果使用了1.1的pipeline,則會出現線頭阻塞問題,這兩個問題都會導致實時性、併發性的問題。

 

  為了解決這些問題,HTTP 2.0 會對 HTTP 的頭進行一定的壓縮,將原來每次都要攜帶的大量 key  value 在兩端建立一個索引表,對相同的頭只傳送索引表中的索引。

  通過在兩端建立固定的http投格式,這樣如果傳送的標頭檔案是固定的,就可以直接指定其對應的索引,減少傳輸資料。

另外,HTTP 2.0 協議將一個 TCP 的連線中,切分成多個流,每個流都有自己的 ID,而且流可以是客戶端發往服務端,也可以是服務端發往客戶端。它其實只是一個虛擬的通道。流是有優先順序的。

 

  HTTP 2.0 還將所有的傳輸資訊分割為更小的訊息和幀,並對它們採用二進位制格式編碼。常見的幀有 Header 幀,用於傳輸 Header 內容,並且會開啟一個新的流。再就是 Data 幀,用來傳輸正文實體。多個 Data 幀屬於同一個流。

  通過這兩種機制,HTTP 2.0 的客戶端可以將多個請求分到不同的流中,然後將請求內容拆成幀,進行二進位制傳輸。這些幀可以打散亂序傳送, 然後根據每個幀首部的流識別符號重新組裝,並且可以根據優先順序,決定優先處理哪個流的資料。

  我們來舉一個例子。

  假設我們的一個頁面要傳送三個獨立的請求,一個獲取 css,一個獲取 js,一個獲取圖片 jpg。如果使用 HTTP 1.1 就是序列的,但是如果使用 HTTP 2.0,就可以在一個連線裡,客戶端和服務端都可以同時傳送多個請求或回應,而且不用按照順序一對一對應。

第14講 | HTTP協議:看個新聞原來這麼麻煩

HTTP 2.0 其實是將三個請求變成三個流,將資料分成幀,亂序傳送到一個 TCP 連線中。

第14講 | HTTP協議:看個新聞原來這麼麻煩

HTTP 2.0 成功解決了 HTTP 1.1 的隊首阻塞問題,同時,也不需要通過 HTTP 1.x 的 pipeline 機制用多條 TCP 連線來實現並行請求與響應;減少了 TCP 連線數對伺服器效能的影響,同時將頁面的多個資料 css、js、 jpg 等通過一個資料連結進行傳輸,能夠加快頁面元件的傳輸速度。

 

HTTP/2解決了HTTP/1.1隊首阻塞問題.但是HTTP2是基於TCP的,TCP嚴格要求包的順序,這不是矛盾嗎?

  研究了一下,發現是不同層的隊首阻塞:

  1. 應用層的隊首阻塞(HTTP/1.1-based head of line blocking): HTTP/1.1可以使用多個TCP連線,但對連線數依然有限制,一次請求要等到連線中其他請求完成後才能開始(Pipeline機制也沒能解決好這個問題),所以沒有空閒連線的時候請求被阻塞,這是應用層的阻塞。 HTTP/2底層使用了一個TCP連線,上層虛擬了stream,HTTP請求跟stream打交道,無需等待前面的請求完成,這確實解決了應用層的隊首阻塞問題。

  2. 傳輸層的隊首阻塞(TCP-based head of line blocking): 正如文中所述,TCP的應答是嚴格有序的,如果前面的包沒到,即使後面的到了也不能應答,這樣可能會導致後面的包被重傳,視窗被“阻塞”在隊首,這就是傳輸層的隊首阻塞。 不管是HTTP/1.1還是HTTP/2,在傳輸層都是基於TCP,那麼TCP層的隊首阻塞問題都是存在的(只能由HTTP/3(based on QUIC)來解決了),另外,HTTP/2用了單個TCP連線,那麼在丟包率嚴重的場景,表現可能比HTTP/1.1更差。

QUIC 協議的“城會玩”

  HTTP 2.0 雖然大大增加了併發性,但還是有問題的。因為 HTTP 2.0 也是基於 TCP 協議的,TCP 協議在處理包時是有嚴格順序的。

 

對於HTTP1.1中管道化導致的請求/響應級別的隊頭阻塞,可以使用HTTP2解決。HTTP2不使用管道化的方式,而是引入了幀、訊息和資料流等概念,每個請求/響應被稱為訊息,每個訊息都被拆分成若干個幀進行傳輸,每個幀都分配一個序號。每個幀在傳輸是屬於一個資料流,而一個連線上可以存在多個流,各個幀在流和連線上獨立傳輸,到達之後在組裝成訊息,這樣就避免了請求/響應阻塞。

 

  當其中一個資料包遇到問題,TCP 連線需要等待這個包完成重傳之後才能繼續進行。雖然 HTTP 2.0 通過多個 stream,使得邏輯上一個 TCP 連線上的並行內容,進行多路資料的傳輸,然而這中間並沒有關聯的資料。一前一後,前面 stream 2 的幀沒有收到,後面 stream 1 的幀也會因此阻塞。

  於是,就又到了從 TCP 切換到 UDP,進行“城會玩”的時候了。這就是 Google 的 QUIC 協議,接下來我們來看它是如何“城會玩”的。

 

  機制一:自定義連線機制

  我們都知道,一條 TCP 連線是由四元組標識的,分別是源 IP、源埠、目的 IP、目的埠。一旦一個元素髮生變化時,就需要斷開重連,重新連線。在移動互聯情況下,當手機訊號不穩定或者在 WIFI 和 行動網路切換時,都會導致重連,從而進行再次的三次握手,導致一定的時延。

  這在 TCP 是沒有辦法的,但是基於 UDP,就可以在 QUIC 自己的邏輯裡面維護連線的機制,不再以四元組標識,而是以一個 64 位的隨機數作為 ID 來標識,而且 UDP 是無連線的,所以當 IP 或者埠變化的時候,只要 ID 不變,就不需要重新建立連線。

  機制二:自定義重傳機制

  TCP 為了保證可靠性,通過使用序號和應答機制,來解決順序問題和丟包問題。

  任何一個序號的包發過去,都要在一定的時間內得到應答,否則一旦超時,就會重發這個序號的包。那怎麼樣才算超時呢?還記得我們提過的自適應重傳演算法嗎?這個超時是通過取樣往返時間 RTT 不斷調整的。

  其實,在 TCP 裡面超時的取樣存在不準確的問題。例如,傳送一個包,序號為 100,發現沒有返回,於是再傳送一個 100,過一陣返回一個 ACK101。這個時候客戶端知道這個包肯定收到了,但是往返時間是多少呢?是 ACK 到達的時間減去後一個 100 傳送的時間,還是減去前一個 100 傳送的時間呢?事實是,第一種演算法把時間算短了,第二種演算法把時間算長了。

  QUIC 也有個序列號,是遞增的。任何一個序列號的包只傳送一次,下次就要加一了。例如,傳送一個包,序號是 100,發現沒有返回;再次傳送的時候,序號就是 101 了;如果返回的 ACK  100,就是對第一個包的響應。如果返回 ACK  101 就是對第二個包的響應,RTT 計算相對準確。

  但是這裡有一個問題,就是怎麼知道包 100 和包 101 傳送的是同樣的內容呢?QUIC 定義了一個 offset 概念。QUIC 既然是面向連線的,也就像 TCP 一樣,是一個資料流,傳送的資料在這個資料流裡面有個偏移量 offset,可以通過 offset 檢視資料傳送到了哪裡,這樣只要這個 offset 的包沒有來,就要重發;如果來了,按照 offset 拼接,還是能夠拼成一個流。

第14講 | HTTP協議:看個新聞原來這麼麻煩

機制三:無阻塞的多路複用

  有了自定義的連線和重傳機制,我們就可以解決上面 HTTP  2.0 的多路複用問題。

  同 HTTP 2.0 一樣,同一條 QUIC 連線上可以建立多個 stream,來傳送多個 HTTP 請求。但是,QUIC 是基於 UDP 的,一個連線上的多個 stream 之間沒有依賴。這樣,假如 stream2 丟了一個 UDP 包,後面跟著 stream3 的一個 UDP 包,雖然 stream2 的那個包需要重傳,但是 stream3 的包無需等待,就可以發給使用者。

機制四:自定義流量控制

  TCP 的流量控制是通過滑動視窗協議。QUIC 的流量控制也是通過 window_update,來告訴對端它可以接受的位元組數。但是 QUIC 的視窗是適應自己的多路複用機制的,不但在一個連線上控制視窗,還在一個連線中的每個 stream 控制視窗。

  還記得嗎?在 TCP 協議中,接收端的視窗的起始點是下一個要接收並且 ACK 的包,即便後來的包都到了,放在快取裡面,視窗也不能右移,因為 TCP 的 ACK 機制是基於序列號的累計應答,一旦 ACK 了一個序列號,就說明前面的都到了,所以只要前面的沒到,後面的到了也不能 ACK,就會導致後面的到了,也有可能超時重傳,浪費頻寬。

  QUIC 的 ACK 是基於 offset 的,每個 offset 的包來了,進了快取,就可以應答,應答後就不會重發,中間的空檔會等待到來或者重發即可,而視窗的起始位置為當前收到的最大 offset,從這個 offset 到當前的 stream 所能容納的最大快取,是真正的視窗大小。顯然,這樣更加準確。

第14講 | HTTP協議:看個新聞原來這麼麻煩

另外,還有整個連線的視窗,需要對於所有的 stream 的視窗做一個統計。

 

小結

HTTP 協議雖然很常用,也很複雜,重點記住 GET、POST、 PUT、DELETE 這幾個方法,以及重要的首部欄位;

HTTP 2.0 通過頭壓縮、分幀、二進位制編碼、多路複用等技術提升效能;

QUIC 協議通過基於 UDP 自定義的類似 TCP 的連線、重試、多路複用、流量控制技術,進一步提升效能。

 

兩個思考題吧。

QUIC 是一個精巧的協議,所以它肯定不止今天我提到的四種機制,你知道它還有哪些嗎?

 

這一節主要講了如何基於 HTTP 瀏覽網頁,如果要傳輸比較敏感的銀行卡資訊,該怎麼辦呢?

 

Keep-Alive的作用,

結合tcp的知識, 終於是徹底搞清楚了. 其實就是瀏覽器訪問服務端之後, 一個http請求的底層是tcp連線, tcp連線要經過三次握手之後,開始傳輸資料, 而且因為http設定了keep-alive,所以單次http請求完成之後這條tcp連線並不會斷開, 而是可以讓下一次http請求直接使用.當然keep-alive肯定也有timeout, 超時關閉.

相關文章