Http協議和IO模型

HTTP 協議和IO模型

一:HTTP協議

http協議:HyperText Transfer Procotol超文本傳輸協議,http協議是無狀態的,監聽在80端口,TCP協議上。HTTP協議的特點有以下幾點:

1.支持客戶/服務器模式。
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不同。
由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
3.靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4.無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

在服務器不是持久連接的狀況下,客戶端在第一次訪問服務器時服務器會記錄客戶端的個人標誌信息,當客戶端刷新或者再次訪問時,服務器就要要求客戶端輸個人的標識信息,記錄訪問者的信息。也就是說在不是持久連接的狀況下,服務器無法追蹤訪問者的來源。

於是就出現了 cookiesession

htmlHyperText Mark Language:超文標記語言

web資源:

       靜態文件:.jpg .gif .html  .txt .js .css.mp3 .avi

       動態文件:.php  .jsp

http早期版本只能傳輸文本內容,到HTTP/1.0之後支持MIME。使HTTP協議支持傳輸多媒體信息。

MIMEMultipurpose Internet Mailextention

MIME類型:Major/minor

text/plain

image/jpeg

image/gif

URI:Uniform Resource Idetifier :統一資源標識符

       URLUniform Resource Locate:統一資源定位符

       用於描述某服務特定資源的位置

       Scheme://Server:Poert/Path/to/resource

       URNUniform Resource Naming:統一資源命名符。

       URL方案:scheme

       服務器地址:IPPort

       資源路徑

    基本語法:               

            <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

params:參數

        http://www.kk.com/bbs/hello;gender=f

query:查詢

       http://www.kk.com/bbs/item.php?usesrname=tom&title=abc

frag:片段

request 報文語法格式:

       <method><request-URL> <http/Version>

       <headers>

       <entity-body>

reponse報文語法格式:

<http/version><status> <reason-phrase>

<headers>

<entity-body>

各個字段的介紹:

method:請求的方法:

常用請求的方法:

GET:從服務器獲取一個資源

HEAD:只從服務器獲取文檔的響應首部

POST:向服務器發送要處理的數據

PUT:將請求的主題部分存儲服務器上

DEETE:強求刪除服務器上指定的文檔

TRACE:追蹤請求到達服務器中間經過的代理服務器

OPTIONS:請求服務器返回對指定資源支持使用的請求方法

wKiom1YuR1CAOOuRAAPq6JdvCEA938.jpg

status(狀態碼):告訴客戶端的請求發生的結果:

1XX100-101,信息提示

2XX200-206,成功類型信息

3XX300-305,重定向的資源

4XX400-415,錯誤類型的信息,客戶端的錯誤,

5XX500-505,錯誤類型錯誤,服務器端錯誤

常用的狀態碼:

200:成功響應,請求的所有數據通過相應報文的entity-body部分發送,OK

301:請求的URL執行的資源已經被刪除;但在相應報文中通過首部Location指明瞭資源的所在位置;Moved Permanently (永久重定向)

302:與301相似,但在相應報文中通過首部Location指明瞭資源現在所處臨時新位置;Found  (臨時重定向)

304:客戶端發出了條件式請求,但服務器的資源爲曾發生改變,則通過相應此響應狀態碼通知客戶端,Not Modified

401:需要輸入賬號和密碼認證方能訪問資源:Unauthorized

403:請求被禁止:Forbidden

404:服務器無法找到客戶端請求的資源:Not Found

500:服務器內部錯誤:InternalServerError

502:代理服務器從後端服務器中收到的一條僞響應:Bad Gateway

hearders首部:

通用首部:

Date:報文的創建時間

Connection:連接狀態,keep-alive,close

via:顯示報文經過的中間節點

Cache-Control:控制緩存

no-cache

max-age

Transfer-Encoding

WEB 服務器表明自己對本響應消息體(不是消息體裏面的對象)作了怎樣的編碼,比如是否分塊(chunked),例如:Transfer-Encoding: chunked

pragma

請求首部:

wKioL1YuSDSwccByAAIF9PzfssA977.jpg

Accept:通過服務器自己能夠接受的媒體類型

Accept_Charset

Accept_Encoding:告訴服務器自己能接受的編碼格式,如gzip

Accept-Language:通知服務器自己能接受的語言

 

Host:請求的服務器名稱或者端口號

Referer:包含了當前正在請求的資源的上一級資源。

User-Agent:客戶端代理

條件式請求首部

       Expect

       If-Modified-Since:自從指定的時間之後,請求的資源是否發生過修改

       If-Unmodufied-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:告訴客戶端真正的實體位於何處

Content-encoding:編碼格式

Content-language

Content-Length:實體的長度

Content-Location:實體真正所在的位置

Content-Type:主體的對象類型

緩存相關:

       Etag:實體的擴展標籤

       Expires:實體的過期時間

web頁面,多個資源:

瀏覽器自身的限制是針對於單一域名訪問的限制,最多能打開幾個線程進行訪問,。而在一個公司網站使用多個域名的話,當用戶使用瀏覽器訪問時,瀏覽器會針對不同的域名開啓多個線程來訪問頁面資源。如,在單一域名www.kkkkk.com進行訪問,瀏覽器可能開啓2個線程進行頁面資源的訪問。假如在www.kkkkk.com域名下的圖片資源又單獨使用一個域名www.image.com。那麼瀏覽器會再次開啓兩個線程進行訪問。所以在公司內部使用多個域名,這也是提升訪問速度的一種方法。

1.web服務器的認證:

基於IP認證:

基於用戶認證:

basic認證

digest認證

2.web服務器的資源映射

a.DocumentRoot

b.路徑別名Alias

c.虛擬主機DocumentRoot

b.用戶家目錄DocumentRoot

3.支持第三方模塊:支持模塊的動態加載

 

一次完整的http請求過程

1)建立連接或處理連接:接收客戶端請求或拒絕請求

2)接收請求

       接收來自網絡的請求報文對某一個資源的請求

       併發服務器訪問響應模型(Web I/O

單進程I/O機結構:啓動一個進程處理用戶請求,而且一次只處理一個請求,多個請求被串行響應。

多進程I/O結構:並行啓動多個線程,每個進程響應一個請求,一個請求稱爲一個pv

複用I/O 結構:一個進程響應多個n個請求

                     多線程模型:一個進程生成多個線程,每個線程響應一個用戶請求。

                     事件驅動機制:事件回調來完成事件請求:event-driven

                     複用的多進程I/O結構:啓動多個(m)進程,每個進程響應n個請求。

                     c10K問題 :1w個併發連接:

3)處理請求:對請求報文進行解析,並獲取請求的資源及請求方法等相關信息

              元數據:請求報文首部

              請求方法<method>

                     <method><URL><VerSion>

4)訪問資源:獲取請求報文中請求的資源

web服務器,即存放了web資源的服務器,負責向請求者提供對方請求的靜態資源,或動態運行後生成的資源,這些資源放置在本地文件系統某路徑下,此路徑通常爲DocRoot

              web服務器資源路徑的映射方式:

                     a.docroot

                     b.路徑別名

                     c.虛擬主機docroot

                     b.用戶家目錄docroot

5)構建響應報文

              MIME類型:

                     顯示分類

                     魔法分類

                     協商分類

              URL重定向:

                     cdn

                     web服務構建的響應並非客戶端請求的資源,而是資源另一個訪問路徑。

                     遊走重定向:

                     永久重定向:

6)發送響應報文

7)記錄日誌


二:I/O模型

I/O類型:

同步IO和異步IOsynchronous ,asyncronous:關注的是消息通知機制

同步:調用發出之後不會立即返回,但一旦返回,則返回最終結果。

異步:調用發出之後,被調用方立即返回消息,但返回的並不是最終結果被調用者通過狀態,通知機制等通知調用者,或通過回調函數來處理結果。

阻塞IO和非阻塞IOnlocknonlock

關注的是調用者等待被調用者返回調用結果時的狀態:(調用者的狀態)

阻塞:調用結果返回之前,調用者會被掛起;調用真只有在得到調用結果之後才能繼續。

非阻塞:調用者在調用結果返回之前,不會被掛起,即調用不會阻塞調用者

常用的IO模型:

blocking IO :阻塞型IO

noblocking IO

IO multiplexing:複用型IO

signal driven IO:事件驅動型IO

asynchronnous IO:異步型IO

通過磁盤IO總體解釋:

一個用戶進程發起一次磁盤IO調用時,將有兩個階段組成,一次是內核向磁盤取數據,存放到內存空間,另一次是數據從內存空間取出,將數據存到用戶進程的內存中。真正被稱爲執行IO的階段是:數據從內核內存到進程內存的過程。

1.阻塞型IO

 wKiom1YuSYHg555OAAFBdZqmgNw009.jpg

 

當用戶進程調用了recvfrom這個系統調用,kernel就開始了IO的第一個階段:準備數據(對磁盤read來說內核從磁盤獲取數據)。對於network io來說,很多時候數據在一開始還沒有到達(比如,還沒有收到一個完整的UDP包),這個時候kernel就要等待足夠的數據到來。而在用戶進程這邊,整個進程會被阻塞。當kernel一直等到數據準備好了,它就會將數據從kernel中拷貝到用戶內存,然後kernel返回結果,用戶進程才解除block的狀態,重新運行起來。

所以,blocking IO的特點就是在IO執行的兩個階段(等待數據和拷貝數據兩個階段)都被block了。

實際上,除非特別指定,幾乎所有的IO接口 ( 包括socket接口 ) 都是阻塞型的。這給網絡編程帶來了一個很大的問題,如在調用send()的同時,線程將被阻塞,在此期間,線程將無法執行任何運算或響應任何的網絡請求。

    一個簡單的改進方案是在服務器端使用多線程(或多進程)。多線程(或多進程)的目的是讓每個連接都擁有獨立的線程(或進程),這樣任何一個連接的阻塞都不會影響其他的連接。具體使用多進程還是多線程,並沒有一個特定的模式。傳統意義上,進程的開銷要遠遠大於線程,所以如果需要同時爲較多的客戶機提供服務,則不推薦使用多進程;如果單個服務執行體需要消耗較多的CPU資源,譬如需要進行大規模或長時間的數據運算或文件訪問,則進程較爲安全。

2.非阻塞IO

wKiom1YuSs3wHW3AAAHDBGG0xOA373.jpg

從圖中可以看出,當用戶進程發出read操作時,如果kernel中的數據還沒有準備好,那麼它並不會block用戶進程,而是立刻返回一個error。從用戶進程角度講 ,它發起一個read操作後,並不需要等待,而是馬上就得到了一個結果。用戶進程判斷結果是一個error時,它就知道數據還沒有準備好,於是它可以再次發送read操作。一旦kernel中的數據準備好了,並且又再次收到了用戶進程的system call,那麼它馬上就將數據拷貝到了用戶內存,然後返回。

3.複用型IO

內核提供了兩種調用,select(),poll(),當用戶進程發起系統調用時,內核中的selecte會接受這個系統調用,並select自身將系統調用發送給內核,內核再進行準備數據和拷貝數據。當用戶進程發起一次系統調用給select之後,用戶進程在等待數據返回的過程中,還可以發起多次系統調用,每次系統調用都要經過select發送內核進行處理。也就是說,selects是一個代理。比如,(例子不是很恰當)公司老闆向人事部發布通知要裁員,此時老闆通過助理把裁員名單送給人事部。在發送和得到結果之前,公司老闆還可以通過助理讓銷售部經理來老闆辦公室。其實這就相當於複用IO的模型,助理就相當於select

select不能超過1024個。

prefork模型和worker模型就是基於複用IO模型的。併發響應有限。

調用者被阻塞者select上,但可以處理其他請求或IO

4.事件驅動型IO

wKioL1YuTJWgT8LNAAEZOQlK9P8290.jpg    

事件驅動型IO

在第一階段內:當用戶進程發起系統調用時,內核會立即通知給用戶進程系統調用已經收到,並且會在數據收集和準備完成時通知用戶進程。此時用戶進程就可以處理其他事物。

在第二階段內:當系統將磁盤數據取到內存空間中後,通知調用者,調用者會使用回調函數進行處理,來獲取數據。這個階段會發生阻塞狀況。

假如一個用戶進程在第一次發送系統調用請求後,在第一階段內,繼續發送第二次系統調用請求。當用戶進程第一次請求被阻塞第二階段時,內核告知用戶進程,第二次請求的數據也已經準備好了,讓用戶進程來獲取。此時就出現了衝突狀態

通知機制:

水平觸發:多次通知

邊緣觸發:只通知一次:

event模型就是使用的此IO模型。

Nginx支持此IO模型,採用的通知機制爲邊緣觸發。

5.異步型IO

wKioL1YuTOzQtsvEAAEzXnvaM10984.jpg

異步IO模型和複用IO模型區別之處就是:在數據準備第二階段,內核將數據直接存放到用戶進程的內存空間中,不需要用戶進程使用回調函數從內核中獲取數據。如當一個web服務進程發送請求後,後續過程直接交給內核,在內核處理的過程時間內,此進程可以響應其他的用戶請求。當內核將數據返回到進程內存中後,進程就可以把數據直接返回給用戶,這大大提高了響應的速度。

Nginx也支持異步IO模型,還可以基於內存映射的機制來完成數據的發放、所以說Nginx併發能力強。


幾種IO模型的比較:

wKiom1YuTS3RosoLAALCyIceEfg549.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章