HTTP權威指南與圖解HTTP讀書筆記

目錄html

 第1章 HTTP概述程序員

  1.1 Web客戶端和服務器web

  1.2 資源數據庫

   1.2.1 URI編程

   1.2.2 URL後端

   1.2.3 URN數組

  1.3 事務瀏覽器

   1.3.1 方法緩存

   1.3.2 狀態碼安全

   1.3.3 Web頁面能夠包含多個對象

  1.4 報文

  1.5 鏈接

   1.5.1 TCP/IP

   1.5.2 鏈接、IP地址及端號

   1.5.3 負責域名解析的DNS服務

   1.5.4 小結:各類協議與HTTP協議的關係

  1.6 Web的結構組件

   1.6.1 代理

   1.6.2 緩存

   1.6.3 網關

   1.6.4 隧道

   1.6.5 Agent代理

 第2章 URL與資源

  2.1 URL的語法

   2.1.1 方案---使用什麼協議

   2.1.2 主機與端口

   2.1.3用戶名和密碼

   2.1.4 路徑

   2.1.5 參數

   2.1.6 查詢字符串

   2.1.7 片斷

  2.2 URL快捷方式

   2.2.1 相對URL

 第3章 HTTP報文

  3.1 報文流

   3.1.1 報文流入源端服務器

   3.1.2 報文向下遊流動

  3.2 報文的組成部分

   3.2.1 報文的語法

   3.2.2 起始行

   3.2.3 首部

  3.3 方法

   3.3.1 安全方法

   3.3.2 GET

   3.3.3 HEAD

   3.3.4 PUT 

   3.3.5 POST

   3.3.6 TRACE

   3.3.7 OPTIONS

   3.3.8 DELETE

  3.4 狀態碼

  3.5 首部

 第4章 鏈接管理

  4.1 TCP鏈接

   4.1.1 TCP的可靠數據管道

   4.1.2 TCP流是分段的、由IP分組傳送

   4.1.3 保持TCP鏈接的正確運行

   4.1.4 用TCP套接字編程

  4.3 HTTP鏈接的處理

   4.3.2 串行事務處理時延

  4.4 並行鏈接

   4.4.1 並行鏈接可能會提升頁面的加載速度

   4.4.2 並行鏈接不必定更快

  4.5 持久鏈接

   4.5.1 持久化以及並行鏈接

  4.6 管道化鏈接

 第5章 Web服務器

  5.1 Web服務器的實現

  5.2 實際的Web服務器會作些什麼

  5.3 第一步——接受客戶端鏈接

   5.3.1處理新鏈接

   5.3.2 客戶端主機名識別

  5.4 第二步——接收請求報文

   5.4.1報文的內部表示法

   5.4.2 鏈接的輸入/輸出處理結構

  5.5 第三步——處理請求

  5.6 第四步——對資源的映射及訪問

   5.6.1 docroot

   5.6.2 目錄列表

   5.6.3 動態內容資源的映射

  5.7 第五步——構建響應

   5.7.1 響應實體和MIME類型

   5.7.2 重定向

  5.8 第六步——發送響應

  5.9 第七步——記錄日誌

 

 

第1章 HTTP概述

 1.1 Web客戶端和服務器

HTTP是使用可靠的數據傳輸協議來用於客戶端和服務器之間的通訊。Web的內容都存放在Web服務器上,由於Web服務器使用的是HTTP協議,因此也被稱爲HTTP服務器。服務器中存放了因特網的數據,當HTTP客戶端發出請求時,服務器會在HTTP響應中回送所請求的數據,以下圖所示:

 1.2 資源

Web服務器時Web資源的宿主,Web資源是Web內容的源頭。Web資源能夠包含不少內容,靜態的、動態的、甚至軟件等等,以下圖所示:

 

1.2.1 URI

每一個Web服務器資源都有一個名字,但服務器資源名都有一個統稱:URI (Uniform Resource Identifier,統一資源標識符)。URI有兩種形式:URL和URN。下圖給出的是絕對URI表示

上圖中的登陸信息(認證)是一個可選項,並不必定要有的。

1.2.2 URL

URL(Uniform Resource Locator,統一資源定位符)。URL描述了一臺特定服務器上某資源的特定位置,可參考下圖:

大部分URL都包含三部分:

第一部分:方案,即訪問資源所使用的協議類型,這部分一般是HTTP協議(http://)

第二部分:給出服務器的因特網地址

第三部分:指定了Web服務器上的某個資源

如今幾乎全部的URI都是URL。

1.2.3 URN

URN(統一資源名),做爲特定內容的惟一名稱來使用,與資源的所在地無關,但目前只是一個想法尚未大範圍使用。

1.3 事務

一個HTTP事務是由一條請求命令和一個響應結果組成的。

1.3.1 方法

HTTP支持幾種不一樣的請求命令,這些命令被稱爲方法,每條HTTP請求報文都包含一個方法,常見方法以下表:

1.3.2 狀態碼

每條HTTP響應報文返回時都會攜帶一個狀態碼,來告知客戶端是否成功或者一些其餘信息,下表爲常見的狀態碼錶:

1.3.3 Web頁面能夠包含多個對象

應用程序完成一項任務時一般會發布多個HTTP事務,以下圖所示,Web瀏覽器發佈一些列HTTP事務來獲取並顯示一個內容豐富的Web頁面。一個Web頁面一般是一組資源的集合。

1.4 報文

HTTP報文是由一行行字符串組成的,而且是純文本,不是二進制代碼,一個簡單事務所使用的HTTP報文以下圖所示:

下面給出一條簡單HTTP請求報文的圖例:

1.5 鏈接

HTTP構成報文後,會經過TCP(傳輸控制協議)從一個地方搬移到另外一地方。 

1.5.1 TCP/IP

HTTP是應用層協議,網絡通訊的具體細節都交給了TCP/IP,其結構可參考下圖:

1.5.2 鏈接、IP地址及端口號

在HTTP客戶端向服務器發送報文以前,須要用網際協議(IP)地址和端口號在客戶端和服務器之間創建一條TCP/IP鏈接,那麼這個地址和端口號如何得到?就是經過URL。下圖給出了通訊的過程:

上圖中DNS(Domain Name System)服務是和 HTTP 協議同樣位於應用層的協議,它提供域名到 IP 地址之間的解析服務。整個流程以下:

  1.  瀏覽器從URL中解析出服務器的主機名
  2. 瀏覽器將服務器的主機名轉換成服務器的P地址
  3. 瀏覽器將端口號(若是有的話)從URL中解析出來;
  4. 瀏覽器創建一條與Web服務器的TCP鏈接;
  5. 瀏覽器向服務器發送一條HTTP請求報文
  6. 服務器向瀏覽器回送一條HTTP響應報文
  7. 關閉鏈接,瀏覽器顯示文檔

1.5.3 負責域名解析的 DNS 服務

DNS(Domain Name System)服務是和 HTTP 協議同樣位於應用層的協議。它提供域名到 IP 地址之間的解析服務。計算機既能夠被賦予 IP 地址,也能夠被賦予主機名和域名。好比:www.hackr.jp。

那麼DNS 協議提供經過域名查找 IP 地址,或逆向從 IP 地址反查域名的服務。

1.5.4 小結:各類協議與HTTP協議的關係

1.6 Web的結構組件

代理:位於客戶端和服務器之間的HTTP中間實體

緩存:HTTP的倉庫,使經常使用頁面的副本能夠保存在離客戶端更近的地方。

網關:鏈接其餘應用程序的特殊Web服務器

隧道:對HTTP通訊報文進行盲轉發的特殊代理

Agent代理:發起自動HTTP請求的半智能Web客戶端。

1.6.1 代理

HTTP代理服務器時Web安全、應用集成以及性能優化的重要組成模塊。以下圖所示,代理接收全部客戶端的HTTP請求,並將這些請求轉發給服務器(也可能對請求進行修改後轉發),對用戶而言,代理端的應用程序表明用戶訪問服務器。出於安全考慮,一般會將代理做爲轉發全部Web流量的可信任中間節點使用,代理還能夠對請求和響應進行過濾。

1.6.2 緩存

Web緩存或代理緩存是一種特殊的HTTP代理服務器,能夠將代理傳送的經常使用文檔複製保存起來,當下一個請求是同一文檔時即可以從緩存出提取了。客戶端從附近的緩存下載文檔要比從遠程Web服務器下載快不少。

1.6.3 網關

網關( gateway)是一種特殊的服務器,做爲其餘服務器的中間實體使用。一般用於將HTTP流量轉換成其餘的協議。網關接受請求時就好像本身是資源的源端服務器同樣。客戶端可能並不知道本身正在與一個網關進行通訊。

以下圖所示,一個HTTP/FTP網關會經過HTTP請求接收對FTPURI的請求,但經過FTP協議來獲取文檔獲得的文檔會被封裝成一條HTTP報文,發送給客戶端。

1.6.4 隧道

隧道(tunnel)是創建起來以後,就會在兩條鏈接之間對原始數據進行盲轉發的HTTP 應用程序,轉發是不會窺探數據。更通俗一點說法就是:隧道能夠經過HTTP應用程序訪問使用非HTTP協議的應用程序。好比,WEB隧道容許用戶經過HTTP鏈接發送非HTTP流量,這樣就能夠在HTTP上捎帶其餘協議數據了,使用WEB隧道最多見緣由就是要在HTTP鏈接中嵌入非HTTP流量。

好比下圖中,就是經過 HTTP 鏈接承載加密的安全套接字層(SSL,Secure Sockets Layer)流量,這樣 SSL 流量就能夠穿過只容許 Web 流量經過的防火牆了。

 

1.6.5 Agent代理

用戶Agent代理(簡稱Agent代理)是表明用戶發起HTTP請求的客戶端程序,全部發布Web請求的應用程序都是HTTP Agent代理,在前面的分析中只有一種HTTP Agent代理即:Web瀏覽器。但用戶Agent代理還有不少類型,最多見的如「w網絡蜘蛛」,蒐集Web上的內容,在生活常見的就是百度的搜索引擎,能夠從世界範圍內獲取Web界面。

第2章 URL與資源 

2.1 URL的語法

URL提供了一種定位因特網上任意資源的手段,但這些資源能夠經過不一樣的方案來得到,不一樣的方案下其語法可能稍有不一樣。對URL而言最重要的部分是:方案、主機、路徑。下表是通用URL組件

2.1.1 方案---使用什麼協議

方案是規定如何訪問指定資源的主要標識符,它會告訴負責解析URL的應用程序該使用什麼協議,方案名是大小寫無關的。

2.1.2 主機與端口

URL的主機和端口組件提供了哪臺機器裝載了資源,以及在那臺機器的什麼地方能夠找到能對目標資源進行訪問的服務器這兩組信息。

主機組件標識了因特網上可以訪問資源的宿主機器。能夠用主機名或者IP地址來表示主機名。以下面兩個URL表示的同一個資源:http://www.joes-hardware.com:80/index.html、http://161.58.228.45:80/index.htm。端口組件標識了服務器正在監聽的網絡端口。對下層使用了TCP協議的HITP來講,默認端口號爲80。

2.1.3用戶名和密碼

不少服務器都要求輸入用戶名和密碼纔會容許用戶訪問數據。如FTP服務器。當沒有用戶或密碼組件時則會自動插入一個默認的用戶和密碼。

2.1.4 路徑

URL的路徑組件則說明了資源位於服務器的什麼地方,如:http://www.joes-hardware.com:80/seasonal/index-fall.html,這個URL中的路徑爲 /seasonal/ index- -fall.html。每一個路徑段都有本身的參數( param)組件。

2.1.5 參數

爲了嚮應用程序提供它們所需的輸入參數,以便正確地與服務器進行交互,URL中有一個參數組件。這個組件就是URL中的名值對列表,由字符 " ; "將其與URL的其他部分(以及各名值對)分隔開來。它們爲應用程序提供了訪問資源所需的全部附加信息。好比:ftp: //prepai. mit. edu/pub/gnu; type=d在這個例子中,有一個參數type=d,參數名爲type,值爲d。

如前所述,HTTP URL的路徑組件能夠分紅若干路徑段。每段均可以有本身的參數。好比http://www.joes-hardware.com/hammers:sale=false/index.html;graphics=true這個例子就有兩個路徑段, hammers和 index.html。 hammers路徑段有參數sale,其值爲 false。index.html段有參數 graphics,其值爲true。

2.1.6 查詢字符串

以一個查詢URL爲例:http://www.joes-hardware.com/inventory-check.cgi?item=12731。該URL來查詢Web數據庫網關中編號爲12731的條目是否有貨。向號(?)右邊的內容被稱爲查詢( query)組件。URL的査詢組件和標識網關資源的URL路徑組件一塊兒被髮送給網關資源。基本上能夠將網關看成訪向其餘應用程序的訪問點。

下圖爲一個查詢組件的例子,查詢的目的是檢查清單中是否有尺寸爲large、色爲blue的條目12731。

2.1.7 片斷

URL支持使用片斷(frag)組件來表示一個資源的內部片斷,從而引用部分資源或資源的一個片斷。好比,URL能夠指向HTML文檔中一個特定的圖片或小節。

片斷掛在URL的右手邊,最前面有一個字符「#。好比,http://www.joes-hardware.com/tools.html#drill。在這個例子中,片斷dils引用了Joe的五金商店Web服務器上頁面 /tools. html中的一個部分。這部分的名字叫作 drills。HTTP服務器一般只處理整個對象,而不是對象的片斷,客戶端不能將片斷傳送給服務器(參見下圖)。瀏覽器從服務器得到了個資源以後,會根據片斷來顯示你感興趣的那部分資源。

2.2 URL快捷方式

Web客戶端能夠理解並使用幾種URL快捷方式。相對URL是在某資源內部指定一個資源的便捷縮略方式。不少瀏覽器還支持URL的自動擴展,也就是用戶輸入URL的一個關鍵(可記憶的)部分,而後由瀏覽器將其他部分填充起來。

2.2.1 相對URL

URL有兩種方式:絕對的和相對的。絕對URL中包含有訪問資源所需的所有信息。相對URL是不完整的,要從相對URL中獲取訪問資源所需的所有信息,就必須相對於另外一個,被稱爲其基礎(base)的URL進行解析。相對URL是URL的一種便捷縮略記法。好比在資源http://www,joes-hardware.com/tools.html下的HTML文檔中有以下代碼

<a href="./hammers.html">hammers</a>
這個URL看起來是不完整的,但其實是個合法的相對URL。能夠相對於它所在文檔的URL對其進行解釋;在這個例子中,就是相對於Joe的五金商店Web服務器的資源//tools.html。
 

第3章 HTTP報文

3.1 報文流

HTTP報文是在HTTP應用程序之間發送的數據塊,這些報文在客戶端、服務器和代理之間流動。其術語流入、流出、上游、下游都是描述報文方向的。

3.1.1 報文流入源端服務器

HTTP使用流入和流出來描述事物處理的方向。報文流入源端服務器,工做完成後,會流回用戶的Agent代理中。

3.1.2 報文向下遊流動

HTTP報文都會向下遊流動,全部報文的發送者都在接收者的上游。在下圖中,對請求報文惡言,代理1位於代理3的上游,但對響應報文來講,它位於代理3的下游。

3.2 報文的組成部分

HTTP報文是簡單的格式化數據塊,以下圖示例。每條報文都包含一條來自客戶端的請求,或一條來自服務器的響應。報文由3部分組成:對報文進行描述的起始行、包含屬性的首部塊、以及可選的、包含數據的主體部分。

起始行和首部就是由行分隔的ASCI文本。實體的主體或報文的主體(或者就稱爲主體)是一個可選的數據塊。與起始行和首部不一樣的是,主體中能夠包含文本或二進制數據,也能夠爲空。在上圖中,首部給出了一些與主體有關的信息。Content-type行說明了主體是什麼,在這個例子中,就是純文本文檔。 Content-length行說明了主體有多大,在這裏就只有19個字節。

3.2.1 報文的語法

此部分只是純粹的語法,所以再也不記錄。 

3.2.2 起始行

全部的HTTP報文都以一個起始行做爲開始,請求報文的起始行說明了要作些什麼,響應報文的起始行說明發生了什麼。在起始行中包含了:請求行、響應行、方法、狀態碼、緣由短語、版本號。關於這些的具體信息此處再也不贅述了,只是給出兩張表供參考、

經常使用的HTTP方法:

狀態碼分類:

 3.2.3 首部

HTTP首部向請求和響應報文中添加了一些附加信息,從本質上來講它們只是一些名/值對的列表。下表爲常見的首部實例。

3.3 方法

3.3.1 安全方法

HTTP定義了一組被稱爲安全方法的方法。GET方法和HEAD方法都被認爲是安全的,這就意味着使用GET或HEAD方法的HTTP請求都不會產生什麼動做。不產生動做,在這裏意味着HTTP請求不會在服務器上產生什麼結果。例如,你須要購買商品時會提交一個POST請求,那麼就會在服務器上產生一個動做,那麼這個動做可能並不必定就是安全的。但安全方法並不必定是什麼動做都不執行,實際上這是由Web開發者決定的。

3.3.2 GET

GET一般用於請求服務器發送某個資源。在下圖中,客戶端用GET方法發起了一次HTTP請求。 

 

3.3.3 HEAD

HEAD方法與GET方法的行爲很相似,但服務器在響應中只返回首部。不會返回實體的主體部分。這就容許客戶端在未獲取實際資源的狀況下,對資源的首部進行檢查。服務器開發者必須確保返回的首部與GET請求所返回的首部徹底相同。

3.3.4 PUT 

PUT方法迴向服務器寫入文檔,有些系統容許用戶建立Web頁面,並用PUT直接將其安裝到Web服務器上去,以下圖示例。

PUT方法的語義就是讓服務器用請求的主體部分來建立一個由所請求的URL命名的新文檔,若是那個URL已經存在的話,就用這個主體來替代它。

3.3.5 POST

POST方法起初是用來向服務器輪入數據的。如今一般會用它來支持HTML的表單。表單中填好的數據一般會被送給服務器,而後由服務器將其發送到它要去的地方。下圖顯示了一個用POST方法發起HTTP請求一一貫服務器發送表單數據的客戶端。

3.3.6 TRACE

客戶端發起一個請求時,這個請求可能要穿過防火牆、代理、網關或其餘一些應用程序。每一箇中間節點均可能會修改原始的HTTP請求。TRACE方法容許客戶端在最終將請求發送給服務器時,看看它變成了什麼樣子。TRACE請求會在目的服務器端發起一個「環回」診斷。行程最後一站的服務器會彈回一條 TRACE響應,並在響應主體中攜帶它收到的原始請求報文。這樣客戶端就能夠查看在全部中間HTTP應用程序組成的請求/響應鏈上,原始報文是否,以及如何被段壞或修改過。 

 

TRACE方法主要用於診斷,也就是說,用於驗證請求是否如願穿過了請求/響應鏈,也能夠用來查看代理和其餘應用程序對用戶請求所產生的效果。

儘管 TRACE能夠很方便地用於診斷,但它確實也有缺點,它假定中間應用程序對各類不一樣類型請求(不一樣的方法一GET、HEAD、POST等)的處理是相同的不少HTTP應用程序會根據方法的不一樣作出不一樣的事情一一好比,代理可能會將POST請求直接發送給服務器,而將GET請求發送給另外一個HTTP應用程序(好比Web緩存)。 TRACE並不提供區分這些方法的機制。一般,中間應用程序會自行決定對 TRACE請求的處理方式。此外TRACE請求中不能帶有實體的主體部分。 TRACE響應的實體主體部分包含了響應服務器收到的請求的精確副本。

3.3.7 OPTIONS

OPTIONS方法請求Web服務器告知其支持的各類功能。能夠詢問服務器一般支持哪些方法,或者對某些特殊資源支持哪些方法。這爲客戶端應用程序提供了一種手段,使其不用實際訪問那些資源就能斷定訪問各類資源的最優方式。下圖顯示了一個使用 OPTIONS方法的請求

3.3.8 DELETE

DELETE方法就是請服務器刪除請求的URL所指定的資源。可是,客戶端應用程序沒法保證刪除操做必定會被執行,由於HTTP規範容許服務器在不通知客戶端的狀況下撤銷請求。

3.4 狀態碼

對於狀態碼此處能夠在網上查找的狀態碼對照表,此處再也不贅述了。

3.5 首部

此處的信息感受只要瞭解便可。

第4章 鏈接管理

4.1 TCP鏈接

客戶端應用程序打開一條TCP/IP鏈接後,能夠鏈接到可能運行在世界任何地方的服務器應用程序。一旦鏈接創建起來,在客戶端和服務器的計算機之間交換的報文就永遠不會丟失、受損或失序。

以下圖示例:http://www.joes-hardware.com:80/power-tools.html瀏覽器收到這個URL時,第(1)~(3)步會將服務器的IP地址和端口號從URL中分離出來。在第(4)步中創建到Web服務器的TCP鏈接,並在第(5)步經過這條鏈接發送一條請求報文。在第(6)步讀取響應,並在第(7)步關閉鏈接。

4.1.1 TCP的可靠數據管道

HTTP鏈接實際上就是TCP鏈接和一些使用鏈接的規則。TCP爲HTTP提供了一條可靠的比特傳輸管道,從TCP鏈接一端填入的字節會從從另外一端以原有的順序、正確地傳送出來。以下圖TCP會按序、無差錯地承載HTTP數據

4.1.2 TCP流是分段的、由IP分組傳送

TCP的數據是經過名爲IP分組(或IP數據報)的小數據塊來發送的。這樣的話,以下圖所示,HTTP就是「HTTP over TCP over IP」這個「協議棧」中的最頂層了。其安全版本HTTPS就是在HTTP和TCP之間插入了一個(稱爲TLS或SSL的)密碼加密層。

HTTP要傳送一條報文時,會以流的形式將報文數據的內容經過一條打開的TCP鏈接按序傳輸。TCP收到數據流以後,會將數據流砍成被稱做段的小數據塊,並將段封裝在IP分組中,經過因特網進行傳輸(參見下圖)。全部這些工做都是由TCP/IP軟件來處理的,HTTP程序員什麼都看不到。

每一個TCP段都是由IP分組承載,從一個IP地址發送到另外一個IP地址的。每一個IP分組中都包括:

  • 一個IP分組首部(一般爲20字節)
  • 一個TCP段首部(一般爲20字節)
  • 一個TCP數據塊(0個或多個字節)。

IP首部包含了源和目的IP地址、長度和其餘一些標記。TCP段的首部包含了TCP端口號、TCP控制標記,以及用於數據排序和完整性檢査的一些數字值。

 

4.1.3 保持TCP鏈接的正確運行

在任意時刻計算機均可以有幾條TCP鏈接處於打開狀態,TCP鏈接是經過4個值來識別的<源IP地址、源端口號、目的IP地址、目的端口號 >,這4個值一塊兒惟一地定義了一條鏈接。IP地址能夠將你鏈接到正確的計算機,而端口號則能夠將你鏈接到正確的應用程序上去。

注意,有些鏈接可能共享端口號或有相同的源IP地址,但不一樣鏈接沒有4個值徹底同樣的。

4.1.4 用TCP套接字編程

操做系統提供了一些操縱其TCP鏈接的工具——套接字,對於這部分的編程感受不重要,重要的是清除TCP客戶端和服務器是如何經過TCP套接字接口進行通訊的,以下圖所示。

咱們從Web服務器等待鏈接(S4)開始。客戶端根據URL斷定出IP地址和端口號,並創建一條到服務器的TCP鏈接(C3)。創建鏈接可能要花費一些時間,時間長短取決於服務器距離的遠近、服務器的負載狀況,以及因特網的擁擠程度。一旦創建了鏈接,客戶端就會發送HTTP請求(C5),服務器則會讀取請求(S6)。一旦服務器獲取了整條請求報文,就會對請求進行處理,執行所請求的動做(S7),並將數據寫回客戶端。客戶端讀取數據(C6),並對響應數據進行處理(C7)。 

注:4.二、4.3小節涉及到了性能的考慮,這部分比較偏向底層TCP在這裏能夠先不看,後面會轉麼學TCP/IP協議的

4.3 HTTP鏈接的處理

4.3.2 串行事務處理時延

若是隻對鏈接進行簡單的管理,TCP 的性能時延可能會疊加起來。好比,假設有一個包含了 3 個嵌入圖片的 Web 頁面。瀏覽器須要發起 4 個 HTTP 事務來顯示此頁面:1 個用於頂層的 HTML 頁面,3 個用於嵌入的圖片。若是每一個事務都須要(串行地創建)一條新的鏈接,那麼鏈接時延和慢啓動時延就會疊加起來。

 此外,有些瀏覽器在對象加載完畢以前沒法獲知對象的尺寸,並且它們可能須要尺寸信息來決定將對象放在屏幕的什麼位置上,因此在加載了足夠多的對象以前,沒法在屏幕上顯示任何內容。在這種狀況下,即便瀏覽器串行裝載對象的進度正常,但用戶面對的倒是一個空白的屏幕,對裝載的進度一無所知。

後面討論了幾種現存和新興的方法,能夠提升HTTP的鏈接性能:

  並行鏈接:經過多條 TCP 鏈接發起併發的 HTTP 請求。

  持久鏈接:重用 TCP 鏈接,以消除鏈接及關閉時延。

  管道化鏈接:經過共享的 TCP 鏈接發起併發的 HTTP 請求。

4.4 並行鏈接

以下圖所示,HTTP 容許客戶端打開多條鏈接,並行地執行多個 HTTP 事務。在這個例子中,並行加載了四幅嵌入式圖片,每一個事務都有本身的 TCP 鏈接,頁面上每一個組件都包含一個獨立HTTP事務

4.4.1 並行鏈接可能會提升頁面的加載速度

包含嵌入對象的組合頁面若是能(經過並行鏈接)克服單條鏈接的空載時間和帶寬限制,加載速度也會有所提升。時延能夠重疊起來,並且若是單條鏈接沒有充分利用客戶端的因特網帶寬,能夠將未用帶寬分配來裝載其餘對象。下圖顯示了並行鏈接的時間線,比串行鏈接要快不少。

4.4.2 並行鏈接不必定更快

並行鏈接的速度可能會更快,但並不必定老是更快。客戶端的網絡帶寬不足時,大部分的時間可能都是用來傳送數據的。在這種狀況下,一個鏈接到速度較快服務器上的HTTP 事務就會很容易地耗盡全部可用的 Modem 帶寬。若是並行加載多個對象,每一個對象都會去競爭這有限的帶寬,每一個對象都會以較慢的速度按比例加載,這樣帶來的性能提高就很小,甚至沒什麼提高。

並且,打開大量鏈接會消耗不少內存資源,從而引起自身的性能問題。實際上,瀏覽器確實使用了並行鏈接,但它們會將並行鏈接的總數限制爲一個較小的值(一般是 4 個)。服務器能夠隨意關閉來自特定客戶端的超量鏈接。

但由於多個組件對象同時出如今屏幕上時,用戶可以看到加載的進展,因此給人的感受多是更快了。

4.5 持久鏈接

當使用瀏覽器瀏覽一個包含多張圖片的 HTML頁面時,在發送請求訪問 HTML頁面資源的同時,也會請求該 HTML頁面裏包含的其餘資源。所以,每次的請求都會形成無謂的 TCP 鏈接創建和斷開,增長通訊量的開銷。 所以,HTTP/1.1容許 HTTP 設備在事務處理結束以後將 TCP 鏈接保持在打開狀態,以便爲將來的 HTTP 請求重用現存的鏈接。

在事務處理結束以後仍然保持在打開狀態的 TCP 鏈接被稱爲持久連。非持久鏈接會在每一個事務結束以後關閉。持久鏈接會在不一樣事務之間保持打開狀態,直到客戶端或服務器決定將其關閉爲止。

4.5.1 持久化以及並行鏈接

並行鏈接能夠提升複合頁面的傳輸速度,但並行鏈接也有一些缺點。

  • 每一個事務都會打開 / 關閉一條新的鏈接,會耗費時間和帶寬。
  • 因爲 TCP 慢啓動特性的存在,每條新鏈接的性能都會有所下降。
  • 可打開的並行鏈接數量其實是有限的。

持久鏈接下降了時延和鏈接創建的開銷,將鏈接保持在已調諧狀態,並且減小了打開鏈接的潛在數量。可是,管理持久鏈接時要特別當心,否則就會累積出大量的空閒鏈接,耗費本地以及遠程客戶端和服務器上的資源。

持久鏈接與並行鏈接配合使用多是最高效的方式。如今,不少 Web 應用程序都會打開少許的並行鏈接,其中的每個都是持久鏈接,下圖實例中就是持久化鏈接與串行鏈接的比較

4.6 管道化鏈接

HTTP/1.1 容許在持久鏈接上可選地使用請求管道。在響應到達以前,能夠將多條請求放入隊列。當第一條請求經過網絡流向地球另外一端的服務器時,第二條和第三條請求也能夠開始發送了。在高時延網絡條件下,這樣作能夠下降網絡的環回時間,提升性能。

第5章 Web服務器

5.1 Web服務器的實現

Web服務器實現了HTTP和相關的TCP鏈接處理。負責管理Web服務器提供的資源,以及對Web服務器的配置、控制及擴展方面的管理。

Web服務器邏輯實現了HTTP協議、管理着Web資源,並負責提供Web服務器的管理功能。Web服務器邏輯和操做系統共同負責管理TCP鏈接。底層操做系統負責管理底層計算機系統的硬件細節,並提供了TCP/IP網絡支持、負責裝載Web資源的文件系統以及控制當前計算活動的進程管理功能。

5.2 實際的Web服務器會作些什麼

(1)創建鏈接一一接受一個客戶端鏈接,或者若是不但願與這個客戶端創建鏈接,就將其關閉

(2)接收請求ー一從網絡中讀取一條HTTP請求報文。

(3)處理請求一對請求報文進行解釋,並採起行動。

(4)訪問資源一訪向報文中指定的資源。

(5)構建響應一一建立帶有正確首部的HTTP響應報文。

(6)發送響應一一將響應回送給客戶端。

(7)記錄事務處理過程一一將與已完成事務有關的內容記錄在一個日誌文件中。

下圖爲基本Web服務器請求的步驟示例

5.3 第一步——接受客戶端鏈接

若是客戶端已經打開了一條到服務器的持久鏈接,可使用那條鏈接來發送它的請求。不然,客戶端須要打開一條新的到服務器的鏈接(回顧第4章,HTTP的鏈接管理技術)。

5.3.1處理新鏈接

客戶端請求一條到Web服務器的TCP鏈接時,Web服務器會創建鏈接,判斷鏈接的另外一端是哪一個客戶端,從TCP鏈接中將IP地址解析出來。一且新鏈接創建起來Web服務器並被接受,服務器就會將新鏈接添加到其現存Web服務器鏈接列表中,作好監視鏈接上數據傳輸的準備。

Web服務器能夠隨意拒絕或當即關閉任意一條鏈接。有些Web服務器會由於客戶端IP地址或主機名是未認證的,或者由於它是已知的惡意客戶端而關閉鏈接。Web服務器也可使用其餘識別技術。

5.3.2客戶端主機名識別

能夠用「反向DNS"對大部分Wcb服務器進行配置,以便將客戶端IP地址轉換成客戶端主機名。Web服務器能夠將客戶端主機名用於詳細的訪問控制和日誌記錄。但要注意的是,主機名查找可能會花費很長時間,這樣會下降Web事務處理的速度。不少大容量Web服務器要麼會禁止主機名解析,要麼只容許對特定內容進行解析。

5.4 第二步——接收請求報文

解析請求報文時,Web服務器會:

  • 解析請求行,査找請求方法、指定的資源標識符(URI)以及版本號,各項之間由一個空格分隔,並以一個回車換行(CRLF)序列做爲行的結束;
  • 讀取以CRLF結尾的報文首部
  • 檢測到以CRLP結尾的、標識首部結束的空行(若是有的話)
  • 若是有的話(長度由 Content- Length首部指定),讀取請求主體

解析請求報文時,Web服務器會不按期地從網絡上接收輸入數據。網絡鏈接可能隨時都會出現延遲。Web服務器須要從網絡中讀取數據,將部分報文數據臨時存儲在內存中,直到收到足以進行解析的數據並理解其意義爲止。

5.4.1報文的內部表示法

有些Web服務器還會用便於進行報文操做的內部數據結構來存儲請求報文。好比,數據結構中可能包含有指向請求報文中各個片斷的指針及其長度,這樣就能夠將這些首部存放在一個快速查詢表中,以便快速訪向特定首部的具體值了(參見下圖)。

 

5.4.2鏈接的輸入/輸出處理結構

高性能的Web服務器可以同時支持數千條鏈接,但這些鏈接的速度和狀況可能各不相同。由於請求可能會在任意時刻到達,因此Web服務器會不停地觀察有無新的Web請求。不一樣的Web服務器結構會以不一樣的方式爲請求服務,以下圖所示。

線程Web服務器(參見圖a)

單線程的Web服務器一次只處理一個請求,直到其完成爲止。一個事務處理結束後,オ去處理下一條鏈接。這種結構易於實現,但在處理過程當中,全部其餘鏈接都會被忽略。這樣會形成嚴重的性能向題,只適用於低負荷的服務器,以及type-o- serve這樣的診斷工具。

多進程及多線程Web服務器(參見圖b)

多進程和多線程Web服務器用多個進程,或更高效的線程同時對請求進行處理。能夠根據須要建立,或者預先建立一些線程/進程。有些服務器會爲每條鏈接分配一個線程/進程,但當服務器同時要處理成百、上千,甚至數以萬計的鏈接時,須要的進程或線程數量可能會消耗太多的內存或系統資源。困此,不少多線程Web服務器都會對線程/進程的最大數量進行限制

複用IO的服務器(參見圖c)

爲了支持大量的鏈接,不少Web服務器都採用了複用結構。在複用結構中,要同時監視全部鏈接上的活動。當鏈接的狀態發生變化時(好比,有數據可用,或出現錯誤時),就對那條鏈接進行少許的處理;處理結束以後,將鏈接返回到開放鏈接列表中,等待下一次狀態變化。只有在有事情可作時纔會對鏈接進行處理,在空閒鏈接上等待的時候並不會綁定線程和進程。

複用的多線程Wcb服務器(參見圖d)

有些系統會將多線程和複用功能結合在一塊兒,以利用計算機平臺上的多個CPU多個線程(一般是一個物理處理器)中的每個都在觀察打開的鏈接(或打開的鏈接中的一個子集),井對毎條鏈接執行少許的任務。

 

5.5 第三步——處理請求

由於在大數章節都在討論這個問題,此處再也不單獨討論

5.6 第四步——對資源的映射及訪問

在Web服務器將內容傳送給客戶端以前,要將請求報文中的URI映射爲web服務器上適當的內容或內容生成器,以識別出內容的源頭。

5.6.1 docroot

Web服務器支持各類不一樣類型的資源映射,但最簡單的資源映射形式就是用請求URI做爲名字來訪問Web服務器文件系統中的文件。一般,Web服務器的文件系統中會有一個特殊的文件夾專門用於存放web內容。這個文件夾被稱爲文檔的根目錄( document root,或 docroot)。Web服務器從請求報文中獲取URI,並將其附加在文檔根目錄的後面。

在下圖中,有一條對/specials./saw- blade.gif的請求到達。這個例子中Web服務器的文檔根目錄爲/usr/local/httpd/files。Web服務器會返回文件/usr/local/httpd/fles/specials/saw-blade. gif

 

1 虛擬託管的docroot

虛擬託管的 Web 服務器會在同一臺 Web 服務器上提供多個 Web 站點,每一個站點在服務器上都有本身獨有的文檔根目錄。虛擬託管 Web 服務器會根據 URI 或 Host 首部的 IP 地址或主機名來識別要使用的正確文檔根目錄。經過這種方式,即便請求URI 徹底相同,託管在同一 Web 服務器上的兩個 Web 站點也能夠擁有徹底不一樣的內容了。

下圖服務器託管了兩個站點:www.joes-hardware.com 和 www.marys-antiques.com。服務器能夠經過 HTTP 的 Host 首部,或根據不一樣的 IP 地址來區分不一樣的Web 站點。

當請求 A 到達時,服務器會獲取文件 /docs/joe/index.html;當請求 B 到達時,服務器會獲取文件 /docs/mary/index.html。

2 用戶的主目錄docroot

Docroot 的另外一種常見應用是在 Web服務器上爲人們提供私有的 Web站點。一般會把那些以斜槓和波浪號(/~)開始,後面跟着用戶名的 URI 映射爲此用戶的私有文檔根目錄。私有 docroot 一般都是用戶主目錄下那個名爲 public_html 的目錄,但也可將其配置爲其餘值。

 

5.6.2 目錄列表

Web 服務器能夠接收對目錄 URL 的請求,其路徑能夠解析爲一個目錄,而不是文件。咱們能夠對大多數 Web 服務器進行配置,使其在客戶端請求目錄 URL 時採起不一樣的動做,好比:返回一個錯誤;不返回目錄,返回一個特殊的默認「索引文件」;掃描目錄,返回一個包含目錄內容的 HTML 頁面。

大多數 Web 服務器都會去查找目錄中一個名爲 index.html 或 index.htm 的文件來表明此目錄。若是用戶請求的是一個目錄的 URL,並且這個目錄中有一個名爲 index.html(或 index.htm)的文件,服務器就會返回那個文件的內容。

5.6.3 動態內容資源的映射

Web 服務器還能夠將 URI 映射爲動態資源——也就是說,映射到按需動態生成內容的程序上去(參見下圖 )。實際上,有一大類名爲應用程序服務器的 Web 服務器會將 Web 服務器鏈接到複雜的後端應用程序上去。Web 服務器要可以分辨出資源何時是動態的,動態內容生成程序位於何處,以及如何運行那個程序。大多數Web 服務器都提供了一些基本的機制以識別和映射動態資源。

5.7 第五步——構建響應

一旦 Web 服務器識別出了資源,就執行請求方法中描述的動做,並返回響應報文。響應報文中包含有響應狀態碼、響應首部,若是生成了響應主體的話,還包括響應主體。

5.7.1 響應實體和MIME類型

若是事務處理產生了響應主體,就將內容放在響應報文中回送過去。響應實體的Content-Type 首部描述了響應主體 MIME 類型。Web 服務器要負責肯定響應主體的 MIME 類型。有不少配置服務器的方法能夠將MIME 類型與資源關聯起來。好比下圖中,Web服務器用MIME類型文件來設置資源輸出的Content-type首部。

 

5.7.2 重定向

Web 服務器有時會返回重定向響應而不是成功的報文。 Web 服務器能夠將瀏覽器重定向到其餘地方來執行請求。重定向響應由返回碼 3XX 說明。Location 響應首部包含了內容的新地址或優選地址的 URI。

5.8 第六步——發送響應

Web 服務器經過鏈接發送數據時也會面臨與接收數據同樣的問題。服務器可能有不少條到各個客戶端的鏈接,有些是空閒的,有些在向服務器發送數據,還有一些在向客戶端回送響應數據。服務器要記錄鏈接的狀態,還要特別注意對持久鏈接的處理。對非持久鏈接而言,服務器應該在發送了整條報文以後,關閉本身這一端的鏈接。對持久鏈接來講,鏈接可能仍保持打開狀態,在這種狀況下,服務器要特別當心,要正確地計算 Content-Length 首部,否則客戶端就沒法知道響應何時結束了。

5.9 第七步——記錄日誌

最後,當事務結束時,Web 服務器會在日誌文件中添加一個條目,來描述已執行的事務。大多數 Web 服務器都提供了幾種日誌配置格式。

第6章 代理 

Web 代理(proxy)服務器是網絡的中間實體。代理位於客戶端和服務器之間,扮演「中間人」的角色,在各端點之間來回傳送 HTTP 報文。

6.1 Web的中間實體 

HTTP 的代理服務器既是 Web 服務器又是 Web 客戶端。HTTP 客戶端會向代理髮送請求報文,代理服務器必須像 Web 服務器同樣,正確地處理請求和鏈接,而後返回響應。同時,代理自身要向服務器發送請求,這樣,其行爲就必須像正確的 HTTP客戶端同樣,要發送請求並接收響應(參考下圖)。

 

 6.1.2 代理與網關的對比

代理鏈接的是兩個或多個使用相同協議的應用程序,而網關鏈接的則是兩個或多個使用不一樣協議的端點。

實際上,代理和網關之間的區別很模糊。因爲瀏覽器和服務器實現的是不一樣版本的HTTP,代理也常常要作一些協議轉換工做。而商業化的代理服務器也會實現網關的功能來支持 SSL 安全協議、SOCKS 防火牆、FTP 訪問,以及基於 Web 的應用程序。

6.2 爲何使用代理

給出幾個實例:

(1)教育網站上兒童安全的因特網過濾器

(2)集中式文檔訪問控制

(3)安全防火牆

(4)Web 緩存,下圖中客戶端一、2則會訪問距離較近的Web代理緩存

(5)反向代理

6.3 代理會去往何處

 這一小節主要解釋在一個網絡結構中部署代理的時候,它會位於何處。

6.3.1 代理服務器的部署 

出口代理:將代理固定在本地網絡的出口點,以便控制本地網絡與大型因特網之間的流量

訪問(入口)代理:被放在 ISP 訪問點上,用以處理來自客戶的聚合請求

反向代理:部署在網絡邊緣,在 Web 服務器以前,做爲替代物

網絡交換代理:理放在網絡之間的因特網對等交換點上,經過緩存來減輕因特網節點的擁塞,並對流量進行監視

 

6.3.2 代理的層次結構

好比下圖,爲三級的代理層次結構

 

 上圖中的層次結構是靜態的,但不必定非得是靜態的,好比下圖,根據不一樣的因素,訪問代理選擇不一樣的處理方式。

6.3.3 代理是如何獲取流量的

修改客戶端:將客戶端配置爲使用代理服務器,客戶端就會將 HTTP 請求有意地直接發送給代理,而不是原始服務器。

修改網絡:在客戶端不知道,或沒有參與的狀況下,攔截網絡流量並將其導入代理。這種代理被稱爲攔截(intercepting)代理

修改 DNS 的命名空間:直接假扮或修改 Web 服務器的名字和 IP 地址,這樣,全部的請求就會發送給這些替代物,而不是服務器了

修改 Web 服務器:將某些 Web 服務器配置爲向客戶端發送一條 HTTP 重定向命令,收到重定向命令後,客戶端會與代理進行通訊

 

6.4 客戶端的代理設置

這一小節主要講客戶端的配置代理的方式,應用型的,所以沒有記錄

第7章 緩存

Web 緩存是能夠自動保存常見文檔副本的 HTTP 設備。當 Web 請求抵達緩存時,若是本地有「已緩存的」副本,就能夠從本地存儲設備而不是原始服務器中提取這個文檔。

7.1 冗餘的數據傳輸

當不少客戶端訪問一個服務器頁面時,服務器會屢次傳輸同一份文檔,每次傳送給一個客戶端。這些相同的字節會在網絡中一遍遍地傳輸,會耗盡昂貴的網絡帶寬,下降傳輸速度,加劇 Web 服務器的負載。

7.2 帶寬瓶頸

不少網絡爲本地網絡客戶端提供的帶寬比爲遠程服務器提供的帶寬要寬,當客戶端以路徑上最慢的網速訪問服務器,此時若是客戶端從一個快速局域網的緩存中獲得了一份副本,那麼緩存就能夠提升性能。

 

 

 

 7.3 瞬間擁塞

突發事件使不少人幾乎同時去訪問一個 Web 文檔時,就會出現瞬間擁塞。由此形成的過多流量峯值可能會使網絡和Web 服務器產生災難性的崩潰。 

 

 

7.4 距離時延

即便帶寬不是問題,距離也可能成爲問題。每臺網絡路由器都會增長因特網流量的時延。即便客戶端和服務器之間沒有太多的路由器,光速自身也會形成顯著的時延。

7.5 命中和未命中的 

緩存是有所幫助的,但緩存沒法保存世界上每份文檔的副本。能夠用已有的副本爲某些到達緩存的請求提供服務。這被稱爲緩存命中(cachehit),參見圖 7-4a。其餘一些到達緩存的請求可能會因爲沒有副本可用,而被轉發給原始服務器。這被稱爲緩存未命中(cache miss)。

 

 

 

 

 7.5.1 再驗證

原始服務器的內容可能會發生變化,緩存要不時對其進行檢測,看看它們保存的副本是否還是服務器上最新的副本。這些新鮮度檢測被稱爲 HTTP 再驗證。

 

緩存能夠在任意時刻,以任意的頻率對副本進行再驗證。但因爲緩存中一般會包含數百萬的文檔,並且網絡帶寬是很珍貴的,因此大部分緩存只有在客戶端發起請求,而且副本舊得足以須要檢測的時候,纔會對副本進行再驗證,這些就涉及到了具體的驗證規則了。

 

成功的再驗證比緩存未命中要快,失敗的再驗證幾乎和未命中的速度同樣。

7.6 緩存的拓撲結構

最簡單的區分結構是分爲:私有緩存和公有代理緩存

 

 

 

私有緩存:好比Web瀏覽器中內建的私有緩存,會將經常使用文檔緩存在你我的電腦的磁盤和內存中,而且容許用戶去配置緩存的大小和各類設置。

公有代理緩存:特殊的共享代理服務器,被稱爲緩存代理服務器或代理緩存,代理緩存會從本地緩存中提供文檔,或者表明用戶與服務器進行聯繫。

7.6.3 代理緩存的層次結構

下圖顯示了一個兩級的緩存層次結構,其基本思想是在靠近客戶端的地方使用小型廉價緩存,而更高層次中,則逐步採用更大、功能更強的緩存來裝載多用戶共享的文檔。

 

 

7.7 緩存的處理步驟

對一條 HTTP GET 報文的基本緩存處理過程包括 7 個步驟:

  (1) 接收——緩存從網絡中讀取抵達的請求報文。

  (2) 解析——緩存對報文進行解析,提取出 URL 和各類首部。

  (3) 查詢——緩存查看是否有本地副本可用,若是沒有,就獲取一份副本(並將其保存在本地)。

  (4) 新鮮度檢測——緩存查看已緩存副本是否足夠新鮮,若是不是,就詢問服務器是否有任何更新。

  (5) 建立響應——緩存會用新的首部和已緩存的主體來構建一條響應報文。

  (6) 發送——緩存經過網絡將響應發回給客戶端。

  (7) 日誌——緩存可選地建立一個日誌文件條目來描述這個事務。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0
相關文章
相關標籤/搜索