http協定及httpd基礎
——以下内容摘自馬哥教育課堂
HTTP/2.0 目前沒有大規模應用
可以檢視相關rfc文檔
一次完整的http工作過程淺析:
(1)處理連接配接
處理用戶端請求——接收/拒絕請求
tcp連接配接怎麼建立——三次握手
tcp連接配接怎麼斷開——四次斷開
tcp連接配接有兩種,持久連接配接和非持久連接配接
tcp連接配接建立以後,請求第一個資源完成後不會立刻斷開,可以基于該連接配接請求第二個資源,這樣可以避免頻繁的建立和斷開連接配接
而如果連接配接建立以後長時間沒有傳輸web資源則會浪費伺服器的連接配接資源,因為web服務可以維持的連接配接數是有上限的。是以tcp連接配接應該設定逾時時長,連接配接超過一定時間沒有傳輸資源,應該斷開以減少資源占用。
(2)接收請求
接收來自于網絡的請求封包中的對某一資源的一次請求過程
深入講解伺服器端程式如何同時響應多個用戶端的請求?——并發通路響應模型(WEB I/O)。有多種類型
①單程序I/O結構:伺服器端隻啟動一個程序且隻能一次響應一個使用者請求,多個用戶端隻能串行通路,具體來說就是當服務程序在處理第一個用戶端請求通路時,第二個用戶端隻能等待直至伺服器處理完第一個請求。
②多程序I/O結構:并行啟動多個程序,每個程序一次隻能響應一個使用者請求。但程序數多了造成頻繁的記憶體切換,并且程序的個數畢竟是有限的,而且程序更加占用記憶體資源,是以響應能力是有限的。
③複用I/O複用結構:
多線程模型:一個程序内部生成多個線程,一個線程可以響應一個使用者請求,這樣一個程序就可以響應多個請求了,這是突破C10K的通路模型
事件驅動機制event-driven:一個程序内部維持一個事件監控器,監控管理多個I/O,這樣一個程序就可以同時接入多個請求了。那麼一個程序如何維持不同程序的連接配接狀态呢?程序内部基于事件回調機制來完成連接配接狀态的追蹤,也就是IO的追蹤,并基于事件回調來完成用戶端的響應。因而實作了一個程序同時與多個程序進行通信。
④複用的多程序I/O結構:啟動多個程序,每個程序響應多個請求。
(3)處理請求:對請求封包進行解析,并擷取請求的資源及請求方法等相關資訊
請求封包有特定格式,首部包含中繼資料
<method><URL><VERSION>:get下載下傳,put上傳,post送出表單
Host:例如www.magedu.com 請求的主機名稱
Connection:
(4)擷取本地資源:擷取請求封包中請求的資源
web伺服器:存放了web資源的伺服器,負責向請求者提供對方請求的靜态資源/動态資源,這些資源放置于本地檔案系統某系統路徑下,此路徑通常稱為DocRoot
httpd預設的DocRoot是/var/www/html/,其目錄下有images/1.jpg,那麼通路URL為http://www.abc.com/images/1.jpg
web伺服器資源路徑映射方式
1.docroot
2.alias
3.虛拟主機docroot
4.使用者家目錄docroot
(5)把資源建構成響應封包
MIME可以對每種可以被通路的類型進行标記和分類,分類方式有:
顯示分類:php等代碼中顯示指明類型
魔法分類:web伺服器自行判定檔案類型
協商分類:伺服器和用戶端協商分類?
資源通路重定向:當通路A資源時,伺服器回應的是另外一個路徑,于是重新發起通路請求。重定向有多種方式:臨時重定向和永久重定向
重定向還能實作負載均衡的效果,例如CDN可以基于重定向到新位置
(6)發送響應封包
(7)記錄日志
把請求者IP和通路資源和處理辦法記錄到日志檔案中
http是協定,應該有相關的實作程式實作其功能。那麼http協定的實作程式有:
httpd(apache)
nginx
lighttpd,性能接近nginx,社群活躍程度沒有nginx高
(web伺服器程式)
應用程式伺服器:既是web伺服器,又能解析動态資源
IIS:解析ASP頁面
tomcat,jetty,jboss,resin:jsp容器,解析JSP頁面
重量級企業應用webshpere,weblogic,oc4j(oracle,少)
www.netcraft.com 定期更新每種web伺服器程式占有的市場佔有率
回顧:
httpd配置檔案的常見配置
Listen指令 Listen [IP:]PORT
KeepAlived {ON|OFF} 持久連結:http協定無狀态的——它無法記錄通路使用者身份資訊,預設情況下,資源擷取彼此是隔離,毫無聯系的,例如一個頁面每個資源的擷取都要三次握手四次斷開來進行的。這是非持久連接配接。頻繁的建立和斷開連接配接會浪費大量的網絡資源和系統資源。是以才有持久連結,隻建立一次連接配接就完成多個資源的傳輸。相關設定參數,除了KeepAlived這個指令外還有相關指令MaxKeepAlivedRequests和KeepAlivedTimeout兩個指令。
MPM:prefork,worker,event并發響應模型
DSO:LoadModule指令, httpd -M|-l檢視裝載的子產品
DocumentRoot 指定站點通路的根目錄,也是檔案系統上某個指定的目錄
站點通路路徑控制可以使用Directory Location來定義
<Directory "">
Options 對目錄中資源通路屬性的設定,常見有Indexes FollowSymLinks,但一般都不建議啟用,使用None即可
Order Allow,Deny 先檢查Deny
Allow from
Deny from
</Directory>
<Location "">
</Location>
DirectoryIndex 定義預設的首頁面的
ErrorLog 錯誤日志
CustomLog 通路日志,需要指明日志的格式
LogFormat %{Referer}i 引用Referer首部的值,Referer是指目前頁面之前的跳轉連結
Alias /URL/ "/PATH/TO/SOMEDIR/"
是另外一種映射方式,還有一種是DocumentRoot
設定預設字元集
基于使用者的通路控制
認證方式:basic,digest(很多浏覽器不支援?)
可以基于URL,可以基于檔案系統路徑
相關指令是
AuthType Basic
AuthName ""
AuthUserFile "/path/to/.htpasswd"
AuthGroupFile
Require user
Require valid-user
Require group
AuthUserFile使用htpasswd指令來建立,也可以使用mysql。
虛拟主機:三種類型,基于ip,基于端口,基于域名
===
http協定進階
URL統一資源定位符,其組成部分:
URL方案:scheme---http://,https://
服務位址:FQDN/IP:PORT---www.abc.com[:80]
資源路徑:/bbs/index.php,通常是DocumentRoot下的子目錄和子檔案
URL文法進一步說明:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
<user>:<password> 登入的賬号密碼
;<params> 參數,用來指明填入表單的資料
例如http://www.abc.com/bbs/hello;gender=f,隻查詢女性使用者
?<query> 資料庫查詢
動态站點中,有應用程式的腳本檔案,這個腳本檔案需要在伺服器背景運作後才把結果傳回。程式由指令+資料構成,指令存在于腳本檔案中,而資料則在資料庫中。query中含有資料庫查詢的語句。
例如 http://www.abc.com/bbs/item.php?username=tom&title=tiger
#<frag> 錨點
百度百科的很多文檔都有#錨定符
URL有兩種——
相對URL:相對目前路徑擷取下一個資源的路徑指明方式,站内引用可以用
絕對URL:從DocumentRoot開始指明資源路徑,跨站引用隻能使用絕對URL
http協定
http/0.9
http/1.0
http/1.1,加強了緩存功能
http/2.0
http協定是stateless無狀态的
無狀态是指:伺服器無法持續追蹤通路者來源。具體來說,用戶端基于http協定擷取伺服器多個資源時,伺服器并不能識别擷取這些資源的連接配接是否來自于同一個使用者。例如,某個使用者輸入賬号密碼登入後,由于伺服器無法判定請求是否來自同一使用者,是以一重新整理頁面會要求使用者再次輸入賬号密碼。
是以http協定引入其他機制來追蹤使用者,比如cookie。當某用戶端通路伺服器時,伺服器會發送一小段随機資料給使用者。使用者浏覽器會将其接收下來并儲存于本地檔案系統的特定位置上。後續對該伺服器的通路,用戶端都會帶着這小段資料,伺服器以此來判定請求是來自同一個使用者了。就不再會出現登入後的使用者重新整理頁面需要重新登陸的情況了。那麼,在浏覽器關閉後,是否應該保留cookie資訊呢?對于銀行站點等敏感網站,不應該保留,否則下次無論什麼使用者打開浏覽器便自動登陸銀行網站了。
cookie分類
胖cookie:記錄了使用者通路的詳細資訊,很容易洩露使用者隐私,不建議使用
瘦cookie:僅僅辨別使用者身份,而使用者的更詳細的浏覽資訊則儲存在伺服器中,比如使用者購物車中的物品資訊。session機制可以實作此功能,它能記錄使用者在網站的通路行為,session是關聯到某個使用者cookie上的。session是儲存于記憶體中的一小段資料,記錄了使用者的操作。當使用者帶着cookie來通路時,伺服器會查找與之對應的session資訊,進而得知使用者之前的浏覽資訊。
cookie和session是用來追蹤使用者通路行為的重要手段,進而彌補的http無狀态的缺陷。
http事務
一次完成的http請求就是http事務
一次完整的http請求=一次請求+一次響應
http請求涉及非常多的細節,比如用什麼方法,請求的主機,用戶端支援的編碼格式、http協定版本、支援的語言、浏覽器類型等等,這些内容都需要通知伺服器。那麼這些資訊應該添加到封包的哪一部分呢?那就是應用層的http首部了。
伺服器收到請求後需要做分析,就是分析http請求首部的内容,才能決定如何做出回應。比如分析哪個URL,使用的方法,支援的編碼,協定版本。然後建構響應封包。響應封包中除了請求的資源外也應該包含很多資訊。比如,如果響應成功的話,響應内容應該包含響應狀态碼、過期時間、内容編碼方式等。如果響應失敗的,響應内容應該包含失敗原因,失敗的狀态碼資訊。這麼多的資訊,是通過響應封包的響應首部來發給用戶端的。
請求封包是http請求所需的載體,有特定文法格式
<method><request-URL> <http-version>
<headers>衆多首部
兩次換行
<entity-body>請求主體
響應封包是http響應所需的載體,有特定文法格式
<http-version> <status-code> <reason-phrase>
<headers>
<entity-body>響應主體
method:請求方法,标明了用戶端希望伺服器對資源執行的動作,比如常見方法GET,POST,HEAD
version: HTTP/<major>.<minor> 分别為主版本号和次版本号
status-code:是響應結果的代号,由三位數字構成,如200,301,302,404,502
reason-phrase:狀态碼對應含義的簡要描述
headers:标記請求或響應的屬性,每個請求或響應封包可包含任意個首部;每個首部定義——首部名稱:[空格]首部對應值
entity-body:請求或響應時附加的資料,請求封包的實體可能為空。
請求、響應封包組成部分詳細說明
=
method詳解——
GET:從伺服器擷取一個資源,此時entity-body部分為空
HEAD:隻從伺服器擷取文檔響應首部而無需實體部分的内容
POST:向伺服器發送伺服器需要處理的資料,entity-body部分包含這些資料。
PUT:将請求的主體部分存儲在伺服器上,例如上傳一個文檔到伺服器上,entity-body部分包含需要上傳檔案。這是一個危險的方法。
DELETE:請求删除伺服器上的通過URL指定的文檔
TRACE:追蹤請求到達伺服器中間經過的代理伺服器;
OPTIONS:請求伺服器傳回對指定資源支援使用的請求方法
谷歌浏覽器F12進入調試模式可以看到請求首部和響應首部
http協定檢視或分析的工具--封包嗅探器有tcpdump,tshark,wireshark
狀态碼詳解——
狀态碼有五大類
1xx:100,101,額外資訊提示
2xx:200-206,成功的響應
3xx:300-305,重定向的響應
4xx:400-415,因為用戶端引起的錯誤類資訊
5xx:500-505,因為伺服器端引起的錯誤類資訊
常用的狀态碼
200:成功響應,請求的所有資料通過響應封包的entity-body響應發送,原因短語是OK
301:永久重定向,請求的URL指向的資源被永久移動到新位置,并且在響應封包中通過首部Location指明了資源現在所處的新位置。原因短語是moved permanently
302:臨時重定向,請求的URL指向的資源被臨時移動到新位置,并且在響應封包中通過首部Location指明了資源現在所處的新位置。原因短語是Found
304:用戶端發出了條件式請求指定資源,但伺服器判定此資源未發生改變,則通過此響應碼響應用戶端。原因短語是Not Modified。
401:需要輸入賬号和密碼認證才能通路資源,原因短語是unauthorized
403:請求被禁止,forbidden
404:伺服器無法找到用戶端請求的資源,not found
500: 伺服器内部錯誤,internale server error
502: 代理伺服器從後端伺服器收到了一條僞響應;bad gateway。舉例:用戶端請求代理伺服器,代理伺服器中并沒有緩存此資源,于是請求上遊伺服器,但上遊伺服器傳回了一個錯誤資訊,此時代理伺服器無法進行響應了,于是傳回502
headers首部詳解
首部是鍵值對的格式--name: value
多個首部時,每行寫一個header對,示例如下:
Request Headers
Referer:http://www.it168.com/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Response Headers
Date:Wed, 04 Jan 2017 14:31:57 GMT
Last-Modified:Wed, 21 Dec 2016 00:48:51 GMT
Server:Microsoft-IIS/7.5
首部的分類——五種
通用首部:可用于請求首部和響應首部
請求首部:
響應首部:
實體首部:用于描述實體部分的資訊
擴充首部:
詳解如下:
通用首部:
Date:請求/響應封包的建立時間
Connection:指明是否持久連結
Via:顯示封包經過的中間節點
Cache-Control: 緩存控制
Pragma:和緩存相關
Accept: 用戶端通知伺服器可以接收的媒體類型;
Accept-Charset: 用戶端可以允許接收的字元集,比如UTF-8,GBK,GB2312
Accept-Encoding: 用戶端支援的編碼格式,如gzip,deflate,sdch
Accept-Language: 用戶端支援的語言
Client-IP: 用戶端IP
Host:請求的伺服器名稱和端口号
Referer: 引用目前正在請求資源的上一級資源,-表示直接從浏覽器位址欄輸入位址
User-Agent: 用戶端代理類型,比如手機浏覽器,火狐浏覽器
條件式請求首部:
Expect:
If-Modified-Since: 自從指定的時間之後,請求的資源是否發生過修改;如果未修改響應304,如果修改過響應200和更新後的資源;
If-Unmodified-Since:
If-None-Match: 本地緩存中存儲的文檔的ETag标簽是否與伺服器文檔的ETag不比對;
If-Match:
安全請求首部:
Authorization:向伺服器發送認證資訊,如賬号和密碼;
Cookie: 用戶端向伺服器發送cookie
Cookie2:
代理請求首部:
proxy-authorization: 向代理伺服器認證
資訊性首部:
Age:響應耗費的時長?
Server:伺服器程式名稱和版本
協商首部:某資源有多種表示方式時使用,比如頁面有多國語言,應該傳回哪個?
Accept-Ranges: 伺服器可接受的請求範圍類型?
Vary:伺服器檢視的其他首部清單;
安全響應首部:
Set-Cookie: 向用戶端設定cookie;
Set-Cookie2:
WWW-Authenticate: 來自伺服器的對用戶端的質詢認證表單
實體首部:
Allow: 列出對此資源可使用的請求方法
Location:告訴用戶端實體的真正位置,響應狀态碼為301,302時附加該首部
Content-Encoding: 内容編碼格式
Content-Language:
Content-Length: 主體的大小
Content-Location:實體真正所處的位置
Content-Type:主體的對象類型
緩存相關首部:
ETag: 實體的擴充标簽
Expires:實體的過期時間
Last-Modified: 實體最後一次修改時間
httpd的介紹
美國的工信部?曾經發起一個項目——開發web伺服器程式軟體,是以召集了一批優秀的工程師,後來開發成功。這批工程師散入江湖各大網際網路公司後又自行組織起來重新改進增強這個web伺服器程式,這個程式就是apache(a patchy server = apache)
ASF: apache software foundation
httpd特性:
1、高度子產品化設計(core+module)
2、DSO子產品動态裝載,dynamic shared object
3、MPM機制,多路處理子產品,有如下三種類型:
prefork:多程序模型,每個程序響應一個請求。httpd會以root啟動一個主程序,主程序監聽80端口并負責生成和管理多個子程序。主程序會把使用者請求交個子程序來處理,子程序為工作程序,每個子程序處理一個使用者請求。而子程序并非使用80端口的而是使用随機端口。但是建構響應封包還是使用80端口。子程序響應了使用者請求後,會回收到空閑程序池中而不是立刻銷毀。另外,即使沒有使用者請求,也會預先生成多個空閑程序随時等待請求到來。子程序數<=1024個。這種架構,不能響應大量使用者的通路,但是非常穩定。即使某個程序崩潰了,也隻是影響一個使用者通路罷了而不會影響很多使用者。是以對于使用者量不大的群體,prefork是非常好的選擇。
越精細的東西,越容易出故障。
如果伺服器可以同時響應1024個請求,處理每個請求需要2s,一分鐘處理30*1024個請求。但是請注意,一個頁面可能就包含了100個請求。每天page view(PV)是15萬,中小型企業
worker:多線程響應模型,每個線程響應一個程序。一個主程序生成多個子程序,每個子程序生成多個工作線程,每個線程響應一個使用者請求。
通過這種方式,可以突破1024子程序的限制,因為每個子程序可以生成更多線程來響應使用者請求。這種模型下,子程序和工作線程和prefork一樣也是預先生成以便快速響應使用者請求。但請注意linux排程線程和排程程序方式是相似的,是以使用者通路量大的時候,cpu上還是需要頻繁的上下文切換。
event:事件驅動機制,一個程序響應多個請求
一個主程序生成多個子程序,每個子程序響應多個請求,可以突破C10k的通路模型。http2.2 event是測試使用,http2.4 event可生産使用
http的功能特性:
虛拟主機:支援基于IP,port,FQDN的主機
支援CGI:通用網關接口
反向代理
正向代理
負載均衡
路徑别名
豐富的使用者認證:basic,digest(file,mysql)
支援豐富的第三方子產品
安裝httpd
rpm: yum list all httpd*
源碼編譯安裝:企業中更加常見
本文轉自 zhuhc1988 51CTO部落格,原文連結:http://blog.51cto.com/changeflyhigh/1890225,如需轉載請自行聯系原作者