HTTP結構
第二部分的5章主要介紹了HTTP伺服器,代理,快取,閘道器和機器人應用程式,這些都是Web系統架構的構造模組。
Web伺服器 第五章
Web伺服器會對HTTP請求進行處理並提供響應。術語”web伺服器”可以用來表示Web伺服器的軟體,也可以用來表示提供Web頁面的特定裝置或計算機。
實際的Web伺服器會做些什麼
-
建立連線—-接受一個客戶端連線,或者如果不希望與這個客戶端建立連線,就將其關閉
-
接收請求—-從網路中讀取一條HTTP請求報文
-
處理請求—-對請求報文進行解釋,並採取行動
-
訪問資源—-訪問報文中指定的資源
-
構建響應—-建立帶有正確首部的HTTP響應報文
-
傳送響應—-將響應回送給客戶端
-
記錄事務處理過程—-將與已完成事務有關的內容記錄在一個日誌檔案中
第一步——接受客戶端連線
如果客戶端已經開啟了一條到伺服器的持久連線,可以使用那條連線來傳送它的請求。否則,客戶端需要開啟一條新的到伺服器的連線。
處理新連線
客戶端請求一條道web伺服器的TCP連線時,Web伺服器會建立連線,判斷連線的另一端是哪個客戶端,從TCP連線中將IP地址解析出來。一旦新連線建立起來並被接受,伺服器就會將新連線新增到其現存Web伺服器連線列表中,並做好監視連線上資料傳輸的準備。
客戶端主機名識別
可以用”反向DNS”對大部分Web伺服器進行配置,以便將客戶端IP地址轉換成客戶端主機名。但需要注意的是,主機名的查詢可能會花費很長時間,這樣會降低Web事務處理的速度。因此,很多大容量Web伺服器要麼會禁止主機名解析,要麼只允許對特定內容進行解析。
第二步——接收請求報文
連線上有資料到達時,web伺服器會從網路連線中讀取資料,並將請求報文中的內容解析出來。
解析請求報文時,web伺服器會不定期地從網路上接收輸入資料。網路連線可能隨時都會出現延遲。web伺服器需要從網路中讀取資料,將部分報文資料臨時儲存在記憶體中,直到收到足以進行解析的資料並理解其意義為止。
報文的內部表示法
有些Web伺服器還會用便於進行報文操作的內部資料結構來儲存請求報文,這樣就可以將這些報文的資料存放在一個快速查詢表中,以便快速訪問特定首部的具體值了。
連線的輸入/輸出處理結構
不同的Web伺服器結構以不同的方式為請求服務,如下。
-
單執行緒Web伺服器
-
多程式及多執行緒Web伺服器
-
複用I/O的伺服器
-
複用的多執行緒Web伺服器
第三步——處理請求
一旦web伺服器收到了請求,就可以根據方法,資源,首部和可選的主體部分對請求進行處理了。
第四步——對資源的對映以及訪問
Web伺服器是資源伺服器。他們負責傳送預先建立好的內容,比如HTML頁面或者JPEG圖片,以及執行在伺服器上的資源生成程式所產生的動態內容。在web伺服器將內容傳送給客戶端之前,要將請求報文中的URI對映為Web伺服器上適當的內容或內容生成器,以識別出內容的源頭。
docroot
通常,web伺服器的檔案系統會有一個特殊的資料夾專門用於存放web內容。這個資料夾被稱為文件的根目錄(document root
)。web伺服器從請求報文中獲取URI,並將其附加在文件根目錄的後面。
目錄列表
Web伺服器可以接收對目錄URL的請求,其路徑可以解析為一個目錄,而不是檔案。我們可以對大多數Web伺服器進行配置,使其在客戶端請求目錄URL時採取不同的動作。
-
返回一個錯誤
-
不返回目錄,返回一個特殊的預設”索引檔案” (
DirectoryIndex index.html home.html
) -
掃描目錄,返回一個包含目錄內容的HTML介面 (在Aapche中可以通過指令
Options -Indexes
禁止)
第五步——構建響應
一旦web伺服器識別出了資源,就執行請求方法中描述的動作,並返回響應報文。響應報文中包含了響應狀態碼,響應首部,如果生成了響應主體的話,還包括響應主體。
第六步——傳送響應
Web伺服器通過連線傳送資料時也會面臨與接收資料一樣的問題。伺服器要記錄連線的狀態,還要特別注意對持久連線的處理。對非持久連線而言,伺服器應該在傳送了整條報文之後,關閉自己這一端的連線。
對持久連線來說,連線可能仍保持開啟狀態,在這種情況下,伺服器要特別小心,要正確的計算Content-Length
首部,不然客戶端就無法知道響應什麼時候結束了。
第七步——記錄日誌
當事務結束之後,web伺服器會在日誌檔案中新增一個條目,來描述已執行的事務。
代理 第六章
web上的代理伺服器是代表客戶端完成事務處理的中間人。如果沒有Web代理,HTTP客戶端就要直接與HTTP伺服器進行對話,有了Web代理,客戶端就可以與代理進行對話,然後由代理代表客戶端與伺服器進行交流,客戶端仍然會完成事務的處理,但它是通過代理伺服器提供的優質服務來實現的。
代理與閘道器的區別
嚴格的來說,代理連線的是兩個或多個使用相同協議的應用程式,而閘道器連線的則是兩個或多個使用不同協議的端點。
代理的應用
代理伺服器可以實現各種有用的功能,他們可以改善安全性,提高效能,節省費用。代理伺服器可以看到並接觸所有流過的HTTP流量,所有代理可以監視流量並對其進行修改,以實現很多有用的增值Web服務。
-
兒童過濾器
-
文件訪問控制
-
安全防火牆
-
web快取
-
反向代理
-
內容路由器
-
轉碼器
-
匿名者
代理伺服器的部署
可以根據其目標用途,將代理放在任意位置。
-
出口代理
-
訪問(入口)代理
-
反向代理
-
網路交換代理
層次化的代理
可以通過代理層次結構將代理級聯起來。在代理的層次結構中,會將報文從一個代理傳給另外一個代理,直到最終抵達原始伺服器為止(然後通過代理傳回客戶端)。
如何使用代理
-
修改客戶端的代理配置
-
修改網路,對流量進行攔截並匯入一個代理
-
修改DNS的名稱空間,假扮web伺服器的名字和IP地址。
-
修改Web伺服器,伺服器傳送重定向命令
客戶端的代理設定
-
手工配置
-
預先配置瀏覽器
-
代理的自動配置 PAC
-
WPAD的代理髮行
快取 第七章
web快取是可以自動儲存常見文件副本的HTTP裝置。當Web請求抵達快取時,如果本地有”已快取的”副本,就可以從本地儲存裝置而不是原始伺服器中提取這個文件。
快取可以優化一下問題
-
冗餘的資料傳輸
-
頻寬瓶頸
-
瞬間擁塞
-
距離時延
命中和未命中的
快取無法儲存世界上的每一份文件。可以用已有的副本為某些到達快取的請求提供服務,這被稱為快取命中 (cache hit
),其他一些請求可能因為沒有副本可用,而被轉發給原始伺服器,這被稱為快取未命中(cache miss
)。
-
文件命中率 (說明了阻止了多個通往外部網路的Web事務,有效降低整體時延)
-
位元組命中率 (說明了阻止了多少位元組傳向因特網,有利於節省頻寬)
再驗證
快取可以在任意時刻,以任意頻率對副本進行再驗證。如果驗證過沒有更新則將副本提供給客戶端,這被稱為再驗證命中或緩慢命中,這種方式確實要與原始伺服器進行核對,所以會比單純的快取命中要慢,但它沒有從伺服器中獲取物件資料,所以要比快取未命中快一些。
快取的處理步驟
-
接收——快取從網路中讀取抵達的請求報文
-
解析——快取對報文進行解析,提取出URL和各種首部
-
查詢——快取檢視是否有本地副本可用,如果沒有,就獲取一份副本(並將其儲存在本地)
-
新鮮度檢測——快取檢視已快取副本是否足夠新鮮,如果不是,就詢問伺服器是否有任何更新
-
建立響應——快取會用新的首部和已快取的主體來構建一條響應報文
-
傳送——快取通過網路將響應發回給客戶端
-
日誌——快取可選地建立一個日誌檔案條目來描述這個事務
保持副本的新鮮
文件過期 (document expiration
)
通過特殊的HTTP Cache-Control: max-age = 484200
首部和Expires: Fri, 05,2016, 17:20:30 GMT
首部,HTTP讓原始伺服器向每個文件附加了一個過期日期。在快取文件過期之前,可以以任意頻率使用這些副本,而無需與伺服器聯絡。
HTTP/1.0+的Expires
首部使用的是絕對日期而不是相對時間,所以我們更傾向於使用比較新的HTTP/1.1的Cache-Control
,絕對日期依賴於計算機時鐘的正確設定。
伺服器再驗證 (server revalidation
)
文件過期並不意味著它和伺服器上目前活躍的文件有實際的區別,這只是意味著到了要進行核對的時間了。
-
如果再驗證顯示內容發生了變化,快取會獲取一份新的文件副本,並將其快取在舊文件的位置上,然後將文件傳送給客戶端。
-
如果再驗證顯示內容沒有傳送變化,快取只需要獲取新的首部,包括一個新的過期時間,並對快取中的首部進行更新就行了。
用條件方法進行再驗證
HTTP定義了5個條件請求首部,對快取再驗證來說最有用的2個首部是If-Modified-Since:date
和If-None-Match:tag
(只有兩個條件都滿足時,才能返回304響應)。
另外3個條件首部包括If-Unmodified-Since
(在進行部分檔案的傳輸時,獲取檔案的其餘部分之前要確保檔案未發生變化,此時這個首部是非常有用的),If-Range
(支援對不完整文件的快取)和If-Match
(用於與web伺服器打交道時的併發控制)
If-Modified-Since:Date 再驗證
如果從指定日期之後文件被修改過了,就執行請求的方法。可以與Last-Modified
伺服器響應首部配合使用,只有在內容被修改後與已快取版本有所不同時才去獲取內容。
If-None-Match:實體標籤再驗證
有些情況下僅使用最後修改日期進行再嚴重是不夠的
-
有些文件可能會被週期性地重寫(比如,從一個後臺程式中寫入),但實際包含的資料常常是一樣的。經內容沒有變化,但修改日期會發生變化。
-
有些文件可能被修改了,但所做修改並不重要,不需要讓世界範圍內的快取都重灌資料(比如對拼寫或註釋的修改)
-
有些伺服器無法準確地判定其頁面的最後修改日期
-
有些伺服器提供的文件會在亞秒間隙發生變化(比如,實時監視器),對這些伺服器來說,以一秒為粒度的修改日期可能就不夠用了
為了解決這些問題,HTTP允許使用者對被稱為實體標籤(ETag)的“版本識別符號”進行比較。實體標籤是附加到文件上的任意標籤(引用字串)。
當釋出者對文件進行修改時,可以修改文件的實體標籤來說明這個新的版本,這樣,如果實體標籤被修改了,快取就可以用If-None-Match
條件首部來GET文件的新副本了。
控制快取的能力
伺服器可以通過HTTP定義的幾種方式來指定在文件過期前可以將其快取多長時間。按照優先順序遞減的順序,伺服器可以:
-
Cache-Control: no-store
-
Cache-Control: no-cache
-
Cache-Control: must-revalidate
-
Cache-Control: max-age
-
附加一個Expires日期首部到響應中去
-
不附加過期資訊,讓快取確定自己的過期日期
整合點:閘道器,隧道及中繼 第八章
閘道器 gateway
HTTP擴充套件和介面的發展是由使用者需求驅動的。要在web上釋出更復雜的資源的需求出現時,單個應用程式無法處理所有這些能想到的資源。
為了解決這個問題,開發者提出了閘道器的概念,閘道器可以作為某種翻譯器使用,他可以自動將HTTP流量轉換為其他協議,這樣HTTP客戶端無需瞭解其他協議,就可以與其他應用層序進行互動了。
可以用一個斜槓來分割客戶端和伺服器端協議,並以此對閘道器進行描述<客戶端協議>/<伺服器端協議>
CGI Common Gateway Interface
CGI是一個標準介面集,web伺服器可以用它來裝載程式以響應對特定URL的HTTP請求,並收集程式的輸出資料,將其放在HTTP響應中回送。
隧道
web隧道允許使用者通過http連線傳送非http流量,這樣就可以在http上捎帶其他協議資料了。使用web隧道最常見的原因就是要在http連線中嵌入非http流量,這樣,這類流量就可以穿過只允許web流量通過的防火牆了。
中繼 relay
中繼是沒有完全遵循http規範的簡單http代理。中繼負責處理http中建立連線的部分,然後對位元組進行盲轉發。
Web機器人 第九章
Web爬蟲是一種機器人,它們會遞迴地對各種資訊性Web站點進行遍歷,獲取第一個Web頁面,然後獲取那個頁面指向的所有web頁面,然後是那些頁面指向的所有頁面,以此類推。遞迴地跟蹤這些web連結的機器人會沿著HTML超連結建立的網路”爬行”,所有稱其為爬蟲(crawler
)或蜘蛛(spider
)。
爬蟲
根集
在把爬蟲放出去之前,需要給他一個起始點。爬蟲開始訪問的URL初始集合被稱作根集(root set
)。
避免環路
機器人必須知道他們到過何處,以避免環路(cycle
)的出現。
麵包屑留下的痕跡
管理大規模web爬蟲對其訪問過的地址進行管理時使用的一些有用的技術
-
樹和雜湊表
-
有損的存在點陣圖
-
檢查點
-
分類
別名
由於URL“別名”的存在,即使使用了正確的資料結構,有時也很難分辨出以前是否訪問過某個頁面,如果兩個URL看起來不一樣,但實際指向的是同一資源,就稱這兩個URL互為”別名”。
避免迴圈和重複的一些方法
-
規範化URL
-
廣度優先的爬行
-
節流
-
限制URL大小
-
URL/站點黑名單
-
模式檢測
-
內容指紋
-
人工監視
機器人的HTTP
虛擬主機
機器人實現者要支援Host首部,隨著虛擬主機的流行,請求中不包含Host首部的話,可能會使機器人將錯誤的內容與一個特定的URL關聯起來。
條件請求
對時間戳或實體標籤進行比較,看看它們最近獲取的版本是否已經升級以減少獲取未更新的內容。