HTTP結構

WilsonLiu’s blog 首發地址

HTTP結構

第二部分的5章主要介紹了HTTP服務器,代理,緩存,網關和機器人應用程序,這些都是Web系統架構的構造模塊。

Web服務器 第五章

Web服務器會對HTTP請求進行處理並提供響應。術語”web服務器”可以用來表示Web服務器的軟件,也可以用來表示提供Web頁面的特定設備或計算機。

實際的Web服務器會做些什麼

  1. 建立連接—-接受一個客戶端連接,或者如果不希望與這個客戶端建立連接,就將其關閉
  2. 接收請求—-從網絡中讀取一條HTTP請求報文
  3. 處理請求—-對請求報文進行解釋,並採取行動
  4. 訪問資源—-訪問報文中指定的資源
  5. 構建響應—-創建帶有正確首部的HTTP響應報文
  6. 發送響應—-將響應回送給客戶端
  7. 記錄事務處理過程—-將與已完成事務有關的內容記錄在一個日誌文件中

第一步——接受客戶端連接

如果客戶端已經打開了一條到服務器的持久連接,可以使用那條連接來發送它的請求。否則,客戶端需要打開一條新的到服務器的連接。
處理新連接
客戶端請求一條道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事務,有效降低整體時延)
  • 字節命中率 (說明了阻止了多少字節傳向因特網,有利於節省帶寬)

再驗證

緩存可以在任意時刻,以任意頻率對副本進行再驗證。如果驗證過沒有更新則將副本提供給客戶端,這被稱爲再驗證命中或緩慢命中,這種方式確實要與原始服務器進行覈對,所以會比單純的緩存命中要慢,但它沒有從服務器中獲取對象數據,所以要比緩存未命中快一些。

緩存的處理步驟

  1. 接收——緩存從網絡中讀取抵達的請求報文
  2. 解析——緩存對報文進行解析,提取出URL和各種首部
  3. 查詢——緩存查看是否有本地副本可用,如果沒有,就獲取一份副本(並將其保存在本地)
  4. 新鮮度檢測——緩存查看已緩存副本是否足夠新鮮,如果不是,就詢問服務器是否有任何更新
  5. 創建響應——緩存會用新的首部和已緩存的主體來構建一條響應報文
  6. 發送——緩存通過網絡將響應發回給客戶端
  7. 日誌——緩存可選地創建一個日誌文件條目來描述這個事務

保持副本的新鮮

文檔過期 (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)

文檔過期並不意味着它和服務器上目前活躍的文檔有實際的區別,這只是意味着到了要進行覈對的時間了。

  1. 如果再驗證顯示內容發生了變化,緩存會獲取一份新的文檔副本,並將其緩存在舊文檔的位置上,然後將文檔發送給客戶端。
  2. 如果再驗證顯示內容沒有發送變化,緩存只需要獲取新的首部,包括一個新的過期時間,並對緩存中的首部進行更新就行了。

用條件方法進行再驗證

HTTP定義了5個條件請求首部,對緩存再驗證來說最有用的2個首部是If-Modified-Since:dateIf-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關聯起來。

條件請求

對時間戳或實體標籤進行比較,看看它們最近獲取的版本是否已經升級以減少獲取未更新的內容。

發佈了49 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章