作者簡介
李先生(Lemon),高級運維工程師(自稱),SRE專家(目標),夢想在35歲買一輛保時捷。喜歡鑽研底層技術,認為底層基礎才是王道。一切新技術都離不開操作系統(CPU、內存、磁盤)、網絡等。堅持輸入輸出,記錄自己學習的點滴,在平凡中堅持前行,總有一天會遇見不一樣的自己。公眾號:運維汪(ID:Leeeee_Li)。

一、問題
解釋Web服務器是如何處理HTTP事務的
二、Web服務器
Web服務器會對HTTP請求進行處理並提供響應。Web服務器請求的七大步驟:
1)接受客戶端連接
2)接收請求報文
3)處理請求
4)資源映射及訪問
5)構建響應
6)發送響應
7)記錄日志

1、接受客戶端連接
1)處理新連接
客戶端請求一條到Web服務器的TCP連接時,Web服務器會建立連接,判斷連接的另一端是哪個客戶端,從TCP連接中將IP地址解析出來。一旦新連接建立起來並接受,服務器就會將新連接添加到其現存Web服務器連接列表中,做好監視連接上數據傳輸的准備。Web服務器可以隨意拒絕或立即關閉任意一條連接。有些Web服務器會因為客戶端IP地址或主機名是未認證的,或者因為它是已知的惡意客戶端而關閉連接。Web服務器也可以使用其他技術識別。
2)客戶端主機名識別
可以用”反向DNS“對大部分Web服務器進行配置,以便將客戶端IP地址轉換成客戶端主機名。
Web服務器可以將客戶端主機名用於詳細的訪問控制和日志記錄。需要注意的是,主機名查找可能會花費很長的時間,這樣會降低Web事務處理的速度。很多大容量的Web服務器會禁止主機名解析,或者只允許對特定內容進行解析。
可以用配置指令
Hostnamelookups啟用Apache的主機查找功能。如只打開HTML和CGI資源的主機名解析功能。
HostnameLookups off <Files ~ "\.(html|htm|cgi)$"> HostnameLookups on </Files>
3)通過ident確定客戶端用戶
服務器可以通過ident協議找到發起HTTP連接的用戶名。這些信息對Web服務器的日志記錄特別有用,流行的通用日志格式的第二個字段就包含了每條HTTP請求的ident用戶名。

1)客戶端打開一條HTTP連接
2)服務器打開自己到客戶端ident服務113端口的連接
3)服務器發送一條簡單的請求,詢問與新連接相對應的用戶名,把那個從客戶端解析出包含用戶名的響應
Apache的IdentityCheck on指令告知Apache Web服務器使用ident查找功能,如果沒有ident信息可用,Apache會用連字符(-)來填充ident日志字段。如果沒有ident信息可用,在使用通用日志格式的日志文件中,第二個字段通常都是連字符。
2、接收請求報文
當連接上有數據到達時,Web服務器會從網絡連接中讀取數據,並將請求報文中的內容解析出來。

1)解析請求報文時,Web服務器的工作
1、解析請求行,查找請求方法、指定的資源標識符(URI)以及版本號,各項之間有一個空格隔開,並以一個回車換行(CRLF)序列作為行的結束;
2、讀取以CRLF結尾的報文首部;
3、檢測到以CRLF結尾的、標識首部結束的空行;
4、讀取請求主體
2)報文的內部表示法

3、連接的輸入/輸出處理結構
高性能的Web服務器能夠同時支持數千條連接,每個客戶端都向服務器打開了一條或多條連接。不同的Web服務器會以不同的方式為請求服務。
單線程Web服務器:單線程的Web服務器一次只處理一個請求,直到其完成為止。一個事務處理結束之后,才去處理下一條連接。
多進程及多線程Web服務器:多進程和多線程Web服務器用多個進程,或更高效的線程同時對請求進行處理。
復用I/O的服務器:在復用結構中,要同時監視所有連接上的活動。當連接的狀態發生變化時,就對那條連接進行處理,處理結束后,將連接返回到開放的連接列表中,等待下一次的狀態變化。只有在有事情可以做時才會對連接進行處理,在空閑連接上等待的時候並不會綁定線程和進程。
復用的多線程Web服務器:將多線程和復用功能結合在一起,利用計算機的多個CPU。多個線程中(通常是一個物理處理器)的每一個都在觀察打開的連接,並對每條連接(或打開連接中的一個子集)執行任務。

3、處理請求
當Web服務器接收到請求后,根據方法、資源、首部和可選的主體部分來對請求進行處理。
4、對資源的映射及訪問
1)docroot(文檔的根目錄)
Web服務器的文件系統中有一個專門存放Web內容的目錄,稱為文檔的根目錄(document root,或docroot)。當一個Web服務器的根目錄為/usr/local/httpd/files,並且有一條/special/s.gif的請求到達時,他的訪問如圖

在Apache中,對配置文件httpd.conf添加一行DocumentRoot行就可設置文檔的根目錄
DocumentRoot /usr/local/httpd/files
2)虛擬托管的docroot
虛擬托管的Web服務器會在同一台Web服務器上提供多個Web站點,每個站點在服務器上都有自己都有的文檔根目錄。虛擬托管Web服務器會根據URI或Host首部的IP或主機名來識別要使用的正確的文檔根目錄。通過這種方式,及時請求的URI相同,托管在同一Web服務器上的兩個Web站點也可以擁有完全不同的內存。

A請求進來時,獲取服務器的/doc/aaa/index.html
B請求進來時,獲取服務器的/doc/bbb/index.html
在Apache可配置如下:
<VirtualHost www.aaa.com> ServerName www.aaa.com DocumentRoot /doc/aaa TransferLog /logs/aaa.access_log ErrorLog /1ogs/aaa.error_log </VirtualHost> <VirtualHost www.bbb.com> ServerName www.bbb.com DocumentRoot /doc/bbb TransferLog /logs/bbb.access_log ErrorLog /1ogs/bbb.error_log </VirtualHost>
3)用戶的主目錄docroot
Docroot提供私有的Web站點時,通常會以斜杠和波浪號(/~)開始,如

A請求進來時,獲取服務器的/home/mary/index.html
B請求進來時,獲取服務器的/home/ken/index.html
5、構建響應
一旦Web服務器識別出了資源、就執行請求方法中的描述的動作,並返回響應報文。響應報文中包含有狀態碼、響應首部、如果生成了響應主體的話,還包括響應主體。
1)響應主體
如果事務處理產生了響應主體,就將內容放在響應報文中回送過去。如果有響應主體的話,響應報文中通常包括:
a)描述了響應主體MIME類型的Content-Type首部;
b)描述了響應主體長度的Content-Length首部;
c)實際報文的主題內容
2)MIME類型
Web服務器要負責確定響應主體的MIME類型。

a)根據擴展名確定MIME類型
Web服務器可以用文件的擴展名來說明MIME類型。Web服務器會為每個資源掃描一個包含了所有擴展名的MIME類型的文件,以確定MIME類型。Web服務器用MIME類型文件來設置資源輸出的Content-type首部。
b)魔法分類
Apache Web服務器掃描每個資源的內容,並與一個已知模式表(魔法文件)進行匹配,決定每個文件的MIME類型。
c)顯示分類
對Web服務器進行配置,使其不考慮文件的擴展名和內容,強制特定文件或目錄內容擁有某個MIME類型。
d)類型協商
通過配置Web服務器,使其可以通過與用戶的協商來決定使用哪種格式以及相關的MIME類型。
3)重定向
Web服務器有時會返回重定向響應而不是成功的報文。Web服務器可以將瀏覽器重定向到其他地方來執行請求。重定向響應碼為3XX系列。Location響應首部包含了內容的新地址或優選地址的URL。
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用於此類重定向。
d)負載均衡
一個超載的服務器收到一條請求,服務器可以將客戶端重定向到一個負載不太重的服務器上去。狀態嗎303 See Other以及狀態碼307 Temporary Redirect用於此類重定向。
e)服務器關聯
Web服務器上可能會有某些用戶的本地信息,服務器可以將客戶端重定向到包含了那個客戶端信息的服務器上去。狀態嗎303 See Other以及狀態碼307 Temporary Redirect用於此類重定向。
f)規范目錄名稱
客戶端請求的URL是一個不帶尾部斜線的目錄名時,大多數Web服務器都會將客戶端重定向到一個加了斜線的URL上,這樣相對鏈接就可以正常工作了。
6、發送響應
Web服務器通過連接發送數據,發送數據與接收數據一樣可能有多條到客戶端的連接,有些是空閑的,有些在向服務器發送數據,還有一些在向客戶端回送響應數據。服務器要記錄連接的狀態,還需要特別注意持久連接的處理。對於非持久連接,服務器應該在發送了整條報文之后,關閉自己這一端的連接。
7、記錄日志
當事務結束時,Web服務器會在日志文件中添加一個條目,來描述已執行的事務。
三、學習交流
歡迎大家關注我的公眾號,一起交流、學習。