前端學HTTP之WEB服務器

 前面的話

  Web服務器天天會分發出數以億計的Web頁面,它是萬維網的骨幹。本文主要介紹WEB服務器的相關內容html

 

總括

  Web服務器會對HTTP請求進行處理並提供響應。術語「Web服務器」能夠用來表示Web服務器的軟件,也能夠用來表示提供Web頁面的特定設備或計算機。Web服務器有着不一樣的風格、形狀和尺寸,但無論功能有何差別,全部的Web服務器都可以接收請求資源的HTTP請求,將內容回送給客戶端後端

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

  Web服務器有各類不一樣的形式:能夠在標準的計算機系統上安裝並運行通用的軟件Web服務器;能夠是一臺Web服務器設備,一般會是一臺安裝在機架上的計算機,裏面的軟件會預裝並配置好;在少許計算機芯片上也能夠實現嵌入式Web服務器服務器

【通用軟件Web服務器】網絡

  通用軟件Web服務器運行在標準的、有網絡功能的計算機系統上。能夠選擇開源軟件(好比Apache)或者商業軟件(好比微軟和iPlanet的Web服務器)。基本上全部的計算機和操做系統中都有可用的Web服務器軟件數據結構

【Web服務器設備】多線程

  Web服務器設備(Web server appliance)是預先打包好的軟硬件解決方案。廠商會在他們選擇的計算機平臺上預先安裝好軟件服務器,並將軟件配置好。應用解決方案再也不須要安裝及配置軟件,一般能夠極大地簡化管理工做。可是,Web服務器一般不太靈活,特性不太豐富,並且服務器硬件也不太容易重用或升級app

【嵌入式Web服務器】負載均衡

  嵌入式服務器(embeded server)是要嵌入到消費類產品(好比打印機或家用設備)中去的小型Web服務器。嵌入式Web服務器容許用戶經過便捷的Web瀏覽器接口來管理其消費者設備。有些嵌入式Web服務器甚至能夠在小於一平方英寸的空間內實現,但一般只能提供最小特性功能集性能

  WEB服務器通常要執行如下任務:

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

  二、接收請求——從網絡中讀取一條HTTP請求報文

  三、處理請求——對請求報文進行解釋,並採起行動

  四、訪問資源——訪問報文中指定的資源

  五、構建響應——建立帶有正確首部的HTTP響應報文

  六、發送響應——將響應回送給客戶端

  七、記錄事務處理過程——將與已完成事務有關的內容記錄在一個日誌文件中

  接下來的幾個小節重點說明了Web服務器是怎樣實現這些基本任務的

 

接受鏈接

  若是客戶端已經打開了一條到服務器的持久鏈接,可使用那條鏈接來發送它的請求。不然,客戶端須要打開一條新的到服務器的鏈接

【處理新鏈接】

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

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

【客戶端主機名識別】

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

 

接收報文

  鏈接上有數據到達時,Web服務器會從網絡鏈接中讀取數據,並將請求報文中的內容解析出來

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

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

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

【鏈接的輸入/輸出處理結構】

  高性能的Web服務器可以同時支持數千條鏈接。這些鏈接使得服務器能夠與世界各地的客戶端進行通訊,每一個客戶端都向服務器打開了一條或多條鏈接。某些鏈接可能在快速地向Web服務器發送請求,而其餘一些鏈接則可能在慢慢發送,或者不常常發送請求,還有一些多是空閒的,安靜地等待着未來可能出現的動做

  由於請求可能會在任意時刻到達,因此Web服務器會不停地觀察有無新的Web請求。不一樣的Web服務器結構會以不一樣的方式爲請求服務

a、單線程Web服務器

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

b、多進程及多線程Web服務器

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

c、複用I/O的服務器

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

d、複用的多線程Web服務器

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

 

處理請求

  一旦Web服務器收到了請求,就能夠根據方法、資源、首部和可選的主體部分來對請求進行處理

  有些方法(好比POST)要求請求報文中必須帶有實體主體部分的數據。其餘一些方法(好比OPTIONS)容許有請求的主體部分,也容許沒有。少數方法(好比GET)禁止在請求報文中包含實體的主體數據

 

訪問資源

  Web服務器是資源服務器。它們負責發送預先建立好的內容,好比HTML頁面或JPEG圖片,以及運行在服務器上的資源生成程序所產生的動態內容。在Web服務器將內容傳送給客戶端以前,要將請求報文中的URI映射爲Web服務器上適當的內容或內容生成器,以識別出內容的源頭

【docroot】

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

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

  在配置文件httpd.conf中添加一個DocumentRoot行就能夠爲Apache Web服務器設置文檔的根目錄了:

DocumentRoot /usr/local/httpd/files

  虛擬託管的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

  對大多數Web服務器來講,配置虛擬託管的文檔根目錄是很簡單的。對常見的Apache Web服務器來講,須要爲每一個虛擬Web站點配置一個VirtualHost塊,並且每一個虛擬服務器都要包含DocumentRoot

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

【目錄列表】

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

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

  在Apache Web服務器上,能夠用配置指令DirectoryIndex來配置要做爲默認目錄文件使用的文件名集合。指令DirectoryIndex會按照優先順序列出全部能夠做爲目錄索引文件使用的文件名。下列配置行會使Apache在收到一個目錄URL請求時,在目錄中搜索命令中列出來的任意一個文件:

DirectoryIndex index.html index.htm home.html home.htm index.cgi

  若是用戶請求目錄URI時,沒有提供默認的索引文件,並且沒有禁止使用目錄索引,不少Web服務器都會自動返回一個HTML文件,此文件中會列出那個目錄裏
的文件名,以及每一個文件的大小和修改日期,還包括到每一個文件的URI連接。使用這個文件列表可能會很方便,也能夠經過它在Web服務器上找到一些一般找不到的東西

  能夠經過如下Apache指令禁止自動生成目錄索引文件:

Options - Indexes

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

  Apache容許用戶將URI路徑名組件映射爲可執行文件目錄。服務器收到一條帶有可執行路徑組件的對URI的請求時,會試着去執行相應服務器目錄中的程序。例如,下列Apache配置指令就代表全部路徑以/cgi-bin/開頭的URI都應該執行在目錄/usr/local/etc/httpd/cgi-programs/中找到的相應文件:

ScriptAlias/cgi-bin/usr/local/etc/httpd/cgi-programs/

  Apache還容許用戶用一個特殊的文件擴展名來標識可執行文件。經過這種方式就能夠將可執行腳本放在任意目錄中了。下面的Apache配置指令說明要執行全部以.cgi結尾的Web資源

AddHandler cgi-script .cgi

  CGI是早期出現的一種簡單、流行的服務端應用程序執行接口。現代的應用程序服務器都有更強大更有效的服務端動態內容支持機制,包括微軟的動態服務器頁面(Active Server Page)和Java servlet

  不少Web服務器還提供了對服務器端包含項(SSI)的支持。若是某個資源被標識爲存在服務器端包含項,服務器就會在將其發送給客戶端以前對資源內容進行處理

  要對內容進行掃描,以査找(一般包含在特定HTML註釋中的)特定的模板,這些模板能夠是變量名,也能夠是嵌入式腳本。能夠用變量的值或可執行腳本的輸出來取代特定的模板。這是建立動態內容的一種簡便方式

  Web服務器還能夠爲特定資源進行訪問控制。有請求到達,要訪問受控資源時,Web服務器能夠根據客戶端的IP地址進行訪問控制,也能夠要求輸入密碼來訪問資源

 

構建響應

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

  若是事務處理產生了響應主體,就將內容放在響應報文中回送過去。若是有響應主體的話,響應報文中一般包括:描述了響應主體MIME類型的Content-Type首部;描述了響應主體長度的Content-Length首部;實際報文的主體內容

【MIME 類型】

  Web服務器要負責肯定響應主體的MIME類型。有不少配置服務器的方法能夠將MIME類型與資源關聯起來

  Web服務器能夠用文件的擴展名來講明MIME類型。Web服務器會爲每一個資源掃描一個包含了全部擴展名的MIME類型的文件,以肯定其MIME類型。這種基於擴展名的類型相關是最多見的

  a、魔法分類(Magic typing)

  Apache Web服務器能夠掃描每一個資源的內容,並將其與一個已知模式表(被稱爲魔法文件)進行匹配,以決定每一個文件的MIME類型。這樣作可能比較慢,但很方便,尤爲是文件沒有標準擴展名的時候

  b、顯式分類(Explicit typing)

  對Web服務器進行配置,使其不考慮文件的擴展名或內容,強制特定文件或目錄內容擁有某個MIME類型

  c、類型協商

  有些Web服務器通過配置,能夠以多種文檔格式來存儲資源。在這種狀況下,能夠配置Web服務器,使其能夠經過與用戶的協商來決定使用哪一種格式(及相關的MIME類型)「最好」

  還能夠經過配置Web服務器,將特定的文件與MIME類型相關聯

【重定向】

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

  a、永久刪除的資源

  資源可能已經被移動到了新的位置,或者被從新命名,有了一個新的URL。Web服務器能夠告訴客戶端資源已經被重命名了,這樣客戶端就能夠在重新地址獲取資源以前,更新書籤之類的信息了。狀態碼301 Moved Permanently就用於此類重定向

  b、臨時搬離的資源

  若是資源被臨時移走或重命名了,服務器可能但願將客戶端重定向到新的位置上去。但因爲重命名是臨時的,因此服務器但願客戶端未來還能夠回頭去使用老的URL,不要對書籤進行更新。狀態碼303 See Other以及狀態碼307 Temporary Redirect就用於此類重定向

  c、URL加強

  服務器一般用重定向來重寫URL,每每用於嵌入上下文。當請求到達時,服務器會生成一個新的包含了嵌入式狀態信息的URL,並將用戶重定向到這個新的URL上去。客戶端會跟隨這個重定向信息,從新發起請求,但此次的請求會包含完整的、通過狀態加強的URL。這是在事務間維護狀態的一種有效方式。狀態碼 303 See Other 和 307 Temporary Redirect用於此類重定向

  [注意]有時會將這些通過擴展和狀態加強的URL稱爲"胖URL"

  d、負載均衡

  若是一個超載的服務器收到一條請求,服務器能夠將客戶端重定向到一個負載不過重的服務器上去。狀態碼303 See Other和307 Temporary Redirect可用於此類重定向

  e、服務器關聯

  Web服務器上可能會有某些用戶的本地信息,服務器能夠將客戶端重定向到包含了那個客戶端信息的服務器上去。狀態碼303 See Other和307 Temporary Redirect可用於此類重定向

  f、規範目錄名稱

  客戶端請求的URI是一個不帶尾部斜線的目錄名時,大多數Web服務器都會將客戶端重定向到一個加了斜線的URI上,這樣相對連接就能夠正常工做了

 

發送響應

  Web服務器經過鏈接發送數據時也會面臨與接收數據同樣的問題。服務器可能有不少條到各個客戶端的鏈接,有些是空閒的,有些在向服務器發送數據,還有一些在向客戶端回送響應數據

  服務器要記錄鏈接的狀態,還要特別注意對持久鏈接的處理。對非持久鏈接而言,服務器應該在發送了整條報文以後,關閉本身這一端的鏈接。對持久鏈接來講,鏈接可能仍保持打開狀態,在這種狀況下,服務器要特別當心,要正確地計算Content-Length首部,否則客戶端就沒法知道響應何時結束

 

記錄日誌

  最後,當事務結束時,Web服務器會在日誌文件中添加一個條目,來描述已執行的事務

相關文章
相關標籤/搜索