Web服務之一:Web服務及http協議


http協議的前世今生

HTTP:HyperText Transfer Protocol,超文本傳輸協議;

  主要是用於傳輸超文本的;

  超文本:指的是帶有超級鏈接的文本;

  超鏈接:基於此種鏈接能夠在文檔間實現跳轉。

 

Web:上個世紀80年代末90年代初誕生於歐洲量子物理實驗室,主要用於實現能夠在多個部門之間共享文檔而且可以快速實現文檔定位的一種協議。

 

http/0.9

  在當時,http協議廣泛應用的版本為0.9,那個時候的Web服務僅支持純文本(純文本:由純ASCII字符組成的文本),這種純文本還包括超鏈接,這種超鏈接也是表現為純文本形式的,但這種文本比較獨特,因此稱為超文本(HTML)

 

HTML:HyperText Mark Language,超文本標記語言;這是用於編寫(開發)超文本的語言

  之所以叫標記語言是因為在這種語言當中事先規定好了將語言通過標簽的形式給它加上一些特殊的標記,而這些文本在被用戶客戶端瀏覽器解析時能夠將這些標記解析為字體格式或一些表現屬性,如:<h2>Title</h2>。

 

Browser:瀏覽器,客戶端代理的一種,通過http協議可以訪問服務器端提供的超文本,而Browser能夠在這些文本顯示的時候將標簽解析為對應的修飾的屬性格式。

 

  當Web服務流行開來之后,全球能夠提供Web服務的服務器有很多個,那么每一台服務器上都可以提供各種各樣的文本,甚至於兩台服務器上提供的文本的名字可能是一樣的。如:1.1.1.1上建立了一個Web服務,而這個Web服務提供了一個超文本文檔叫a.html,同時在2.2.2.2主機上也提供了一個a.html。那么對於客戶端來講如何區分這兩個a.html呢?

  因此僅靠文件名進行區分文檔是不可靠的。於是就出現了向URI這樣的機制(雖然URI並不是專門為Web誕生的),URI是很好的能夠讓客戶端識別互聯網上不同文檔的機制。

 

URIUniform Resource Indientifier,統一資源標識符;

  用於定義全局范圍內標記唯一的定位一種資源訪問路徑的方式(命名方式);(不一定是互聯網上的,全球的,包括互聯網在內的可以在全局唯一引用某一個獨立的資源的命名方式)  

  全局范圍:包括但不限於互聯網;

  統一:指的是路徑格式上的統一,無論是什么樣的資源,引用的方式路徑的格式都是規范的。

 

URL:Uniform Resource Locator,統一資源定位符(URI的子對象、子集)

  用於描述在互聯網上互聯網資源的統一表示格式

  格式:protocol://HOST:port/path/to/file

    如:http://www.test.com/download/linux.tar.gz(唯一標識互聯網上的資源)

 

資源(Web資源):

  能夠通過統一資源定位符唯一標記並且能夠讓客戶端訪問的文件(事實上未必都是文件),如:http://www.test.com/logo.gif。每一個能夠訪問的單獨的文件都是一個資源,但是多個資源很可能被整合成一個HTML文檔

 

Web對象:等同於Web資源

  一個HTML文檔就是可以實現將分散在多台Web服務器上的資源整合成一個頁面(可以來自於不同的服務器,因為可能是交叉引用,實現跨主機引用其它主機上的資源的,但可以在同一頁面中予以展示),並且能夠讓瀏覽器予以顯示的語言就是HTML標記語言。

 

HTTP方法:(獲取資源的方式)

  http/0.9時只有一個方法:

    GET,它表示直接從服務器上獲取文檔到本地瀏覽器並予以展示(不是簡單的文件傳輸,而是超文本的文件傳輸);

  在http升級到1.0之后有了更多的方法:

    PUT:從遠程服務器上直接獲取文件到本地,與POST相對應

    POST:與GET相對應,通過表單提交數據到服務器上去;

    DELETE:在遠程服務器上刪除文件,與PUT相對應;

    HEAD:只返回首部,不響應主體;

  對於服務器來講,PUT、POST、DELETE都不安全,因為它們都允許客戶端直接操作服務器上的資源,因此一般來講,需要通過認證以后才能允許客戶端操作。最安全的方法就是GET,GET類似於只讀的意思。

 

MIME機制:

  HTTP1.0更大的改進之處就是引入了MIME機制

  

  MIMEMultipurpose Internet Mail Extension,多功能(用途)互聯網擴展郵件;

 

 

 

    MIME實現了能夠將非文本(如:二進制)數據在傳輸前重新編碼為文本格式再進行傳輸,接收方能夠用相反的方式將其重新還原成原來的格式,還能夠調用相應的程序打開此文件。如:傳輸過去一個rar文件,對方知道這是一個rar壓縮包並且能夠用相應的軟件打開;若傳輸的是圖片就能調用程序打開圖片。所以在MIME編碼當中,Base64就是一種文本編碼格式。

 

 

  SMTP:Simple Mail Transfer Protocol,簡單郵件傳輸協議;

    郵件傳輸協議早期只能傳輸純文本,但后來不僅可以傳輸純文本,還可以傳輸圖片、視頻等二進制文件,因為后來引入了MIME機制。

  


  在http1.0協議當中,也是純文本傳輸的,后來參照了SMTP的純文本傳輸機制將MIME引入到了http協議當中,從此以后,http協議也可以傳輸非文本數據了。

 

  實現過程:在客戶端去獲取某個資源時,資源傳遞到客戶端時,明確說明是哪一類文件,如:是一個image/jpeg格式的圖片,通過http協議的元數據(協議首部),在協議首部里邊明確添加一個首部,告訴對方自己的文件是image/jpeg格式,所以客戶端發現這是一個image大類下的jpeg小子類。此時,瀏覽器調用內部與之相匹配的插件來展示這個文件。若瀏覽器不支持這種插件,可以通過接口調用外部的系統上安裝的其它的能夠顯示文件的插件,以插件的機制在瀏覽器中去解析對應MIME格式的文檔的。因此我們可以發現若未安裝flush插件,打開網頁后許多flush插件是無法顯示的也正是基於此種原理。當然,也正是這種插件機制的實現,使得后來出現了動態網頁的技術。

 

動態效果:

  如:Java,Applet,JRE。嵌入到網頁中,通過http協議傳輸到客戶端,通過JRE環境展示動態效果,但由於過於重量級,在於flash的競爭中落敗。

動態網頁:

  動態網頁指的就是在服務器端存儲的用戶訪問的文檔不再是HTML格式,而是編程語言開發的腳本(也可以是非腳本)。這個腳本在接收參數之后在服務器運行一次,運行完成之后會生成HTML格式的文檔,並且把生成的文檔發送給客戶端。需要注意的是,這個編程語言所開發的腳本在用戶訪問時不是原封不動的發送給客戶端,而是要先獲取客戶端的特性(客戶端獲取資源時需要先發起申請,而在發起申請之前需要把客戶端地址、客戶端瀏覽器的類型等一並發送給服務器),服務器獲取客戶端地址,瀏覽器類型等數據並將這些數據當做參數傳遞給腳本,讓腳本在服務器端執行一次。因此任何一個用戶去訪問,都是根據用戶的特性隨時生成的,所以稱為動態網頁。

  此外,執行腳本與Web服務器沒有任何關系,Web服務器需要調用額外的工具來實現執行腳本。如:建立了一個Web服務器,在Web服務器上建立了一個index.php的文件,當客戶端去申請訪問這個腳本時,服務器會根據它的擴展名來判斷這不是HTML文檔而是一個腳本,此時Web服務器不會立即響應客戶端的訪問,而是通過某種協議或機制去調用額外的運行程序,如:調用PHP的解釋器,讓這個解釋器去運行index.php,這個運行結果自身會生成HTML文檔,將HTML文檔再通過這種協議返回給Web服務器,Web服務器再返回給客戶端;過程:web --> protocol --> php(運行index.php)。需要注意的是,Web服務器只是一個http服務器,它並不負責處理動態內容

 

http請求在服務器端處理的過程詳細描述:(請求分別為靜態網頁與動態網頁時的情況)

  首先我們需要確定的是Web服務器是一個進程,這個進程在用戶空間(Web服務器是一個特殊的具體應用,而既然是具體應用那就是一個具體的軟件,那么這個軟件就應該放在用戶空間)。而用戶所有能夠訪問的網頁文件都存放在磁盤上,因此客戶端向服務器發起請求時,這個請求先到達內核空間,而又因為這個客戶端請求一定是通過網絡協議發送過來的,而協議工作在內核(TCP/IP協議在內核工作),所以首先到達內核,內核空間解析接收到請求后,在內核中通過TCP/IP協議棧中各種路由機制(編碼)等發現這個請求訪問的是本機地址80端口的套接字,因為Web服務一旦啟動之后一定會監聽在TCP協議的80端口之上,因此內核就將請求通過套接字轉交給用戶空間的Web服務器,因此執行流程就從內核空間轉到了用戶空間了。

  若Web服務器發現用戶訪問的是一個文件,如:index.html,此時服務器就得陷入到內核中,重新轉換為內核模式,到磁盤上將文件加載過來,內核找到這個文件后再返回給用戶空間,此時又回到了Web服務器了,Web服務器發現這個文件取出來了就可以響應客戶端了。此時再通過套接字回到內核空間,通過網絡TCP/IP協議棧最終響應給客戶端。

  如果用戶訪問的是動態網頁,就不能直接予以響應了,需要通過其它協議啟動另外一個進程,這個進程一定是一個解釋器,如bash腳本就是bash解釋器,PHP腳本就是PHP解釋器。然后通過協議將這個文件傳遞給這個解釋器或者這個解釋器能夠訪問這個文檔解釋器自己陷入到內核模式將文檔讀取到解釋器中,在解釋其中執行一次,將執行結果返回給Web服務器。Web服務器將請求的結果通過網絡傳遞給客戶端,它需要額外啟動一個進程,進程和服務器之間建立的聯系是通過協議實現的,而在這個進程執行結束后需要銷毀。所以對於Web服務器來講,若要響應一個動態內容,需要先創建一個新的子進程,這個進程執行一次結束后需要將這個進程銷毀,而這都是系統資源開銷,對於一個客戶端訪問可能無所謂,但成千上萬的客戶端訪問呢?因此我們可以推斷到響應動態內容服務器需要更多的系統資源。

 

  在一個HTML網頁中,可能會通過超鏈接引用n個資源(Web對象),而這n個web對象每一個都有自己的URL。而動態網頁生成的HTML結果中也可以引用web對象,這些web對象是靜態的,所以動態網頁包含靜態內容(無需改變或無需執行的內容如:圖片、文件、rar壓縮包)和動態內容(需要執行一次才能返回給客戶端,只有動態內容才需要運行)。在http1.0之后就能支持這些機制了,正是1.0中引入了MIME,使得Web服務對於多媒體的支持得到了極大的擴展,也正是1.0系列的出現,使得web服務器迅速流行開來並大大的促進了互聯網的發展。

  

  我們再來詳細討論一下整個過程:

  以純靜態頁面來講,所有用戶訪問的內容都是一樣的,由此我們來分析一個問題:一個客戶端發起Web服務請求到服務器需要經過多少個層次呢?如在瀏覽器輸入www.test.com訪問,第一步需要把FQDN轉換成IP地址,因此在請求發出之前需要先通過DNS服務器解析FQDN,而DNS服務器可能會遞歸、迭代,需要消耗一些時間(在第一次訪問時,記錄未緩存到本地),之后客戶端輸入地址發送請求給服務器,服務器接收請求后,在內部需要有一個機制能夠接收用戶的請求,這種機制就叫做監聽,監聽在某個端口上,等待客戶端的請求。一旦用戶請求來了,而內核通過TCP/IP協議棧發現有人監聽在這個端口上,於是這個請求就可以交給這個套接字了。但如果本地沒有任何一個用戶進程監聽在某個套接字,但有客戶端來訪問了,此時內核無法知道有誰能夠響應這個請求,此時就會拒絕客戶端請求,如:此地未啟動這個服務,因此必須到內核中去注冊需要使用哪一個端口並一直在這個端口上處於等待狀態。所以當有請求到來時,通過TCP/IP協議的首部解碼后發現用戶訪問的是這么一個端口,於是就把這個請求轉交給這個端口,而進程又一直監聽在這個端口,一旦有請求來了,可進行響應。

 

http報文:

  TCP/IP協議在封裝報文時,TCP首部主要是源端口(Source Port)、目標端口(Destination Port),IP首部主要是源IP地址(Source IP)、目標IP地址(Destination IP)。但卻並沒有明確說明具體訪問哪個文檔或資源,因此某一特定的應用在通過TCP/IP協議往外發送時,TCP/IP最多就是將報文傳遞到目的地,到達目的地后還需要具體協議的報文首部。因此http協議也有自己的首部,叫http首部,它明確定義了基於哪種協議獲取哪個資源的,需要說明獲取什么文檔,如:GET /2.html,並且還需要說明獲取哪個主機的資源,因此通常還有一個首部叫:Host:www.test.com(加主機是HTTP1.0中引入的一種機制,在發起獲取資源請求時,不但要指明獲取哪個資源,還要再加上獲取哪個主機的資源,這個主機一定是主機名稱,這是為虛擬主機做准備的)。說白了,這一切就叫http報文

  IP:

    Source IP

    Destination IP

  TCP:

    Source Port

    Destination Port

  http首部:

    GET/2.html

    Host:www.test.com

 

  http報文分為兩種:請求報文、響應報文。

    報文語法:

    上面兩個報文的第一行稱為報文"起始行(start line)";后面的標簽格式的內容稱作首部域(Header field),每個首部域都由名稱(name)和值(value),中間用逗號分隔,另外,響應報文通常還有一個稱作Body的信息主體,即響應給客戶端的內容。

    請求報文:

    method:資源獲取方法;

    request-URL:請求的資源是什么;

    version:對應請求資源協議的版本號;

    headers:http協議首部;

    headers后的空白行是必須的;

    entity-body:空白行后有一些報文主體(報文內容)

    響應報文:

    version:對應請求的版本

    status:狀態(代)碼,請求結果正確與否的標識符

      狀態碼分為5類:

      1xx:純信息,與請求的資源沒有太大的關系;

      2xx:“成功”類的狀態碼信息,常用狀態碼:200(表示請求資源正常,已獲取到正常響應);

      3xx:重定向類的信息,表示請求的資源已存在,但資源已被挪到其它地方了,如:給了一個參考答案說這個資源已經被挪走了,請重新發起請求另外一個地址,並且把另外的參考地址也響應給客戶端了。常用的狀態碼:301(表示永久重定向,永久的挪到了那個位置了)、302(臨時重定向,繁忙時重定向到指定位置尋找)、304(表示請求的內容未發生任何改變,若緩存過直接使用緩存即可)。需要注意的是,重定向的信息未必都是重定向,如304狀態碼;

      4xx:客戶端錯誤類信息,常用狀態碼:404(請求了一個不存在的文件);

      5xx:服務器端錯誤類信息;

    reason-phrase:定義解釋status的意義;

    headers:響應報文首部;

    entity-body:報文主體;

    報文舉例:

    GET / HTTP/1.1中的/表示訪問一個網站但沒有明確指定訪問哪個頁面,/表示訪問對方的默認頁面(主頁)。

 

緩存:在http/1.0中,引入緩存的機制時為了加速系統訪問、節省網絡帶寬的。

 

Web服務器的主要操作:

1、建立連接——接受或拒絕客戶端的連接請求;

2、接收請求——通過網絡讀取HTTP請求報文;

3、處理請求——解析請求報文並做出相應的動作;

4、訪問資源——訪問請求報文中相關的資源;

5、構建響應——使用正確的首部生成HTTP響應報文;

6、發送響應——向客戶端發送生成的響應報文;

7、記錄日志——當已經完成的HTTP事務記錄進日志文件;

  從上述操作中可以看出,Web服務器沒有執行腳本的過程。因此真正意義上的原生態的Web服務器是不會處理動態內容的

  

  http協議基於TCP協議,每一個TCP的建立都需要3次握手,而拿到資源后需要4次斷開。為了避免每一次訪問資源都要三次握手、四次揮手,推出了http/1.1。

http/1.1:

  增強了緩存功能;

  引入了長連接;

    獲取資源后並不是立即斷開連接,而是繼續獲取下一個資源;而長連接可以讓同一個客戶端發起第二個請求時盡可能縮短時間也降低服務器端資源占用率,但是當服務器端帶寬占用巨大時,后來的客戶端可能很難建立連接了。

    因此,為了資源的有效利用不能讓建立長連接的客戶端永久在線,因此給出兩個限定:1.若請求第一或第二個資源后就不再請求,需要定義一個超時時間,到達一定時間后超時斷開;2.當一直請求不斷開時,定義做多請求多少次,如還請求,需要重新排隊。

 

Web服務器處理模型

  服務器可能會出現多個客戶端請求同時連進來的狀況,那么怎么去響應多個用戶請求呢?  

web服務器處理並發連接請求的架構方式:

  1、單線程web服務器(Single-threaded web server)

  此種架構方式中,web服務器一次處理一個請求,結束后讀取並處理下一個請求。在某請求處理過程中,其它所有的請求將被忽略,因此,在並發請求數較多的場景中將會出現嚴重的必能問題。

 

  2、多進程/多線程web服務器

  此種架構方式中,web服務器生成多個進程或線程並行處理多個用戶請求,進程或線程可以按需或實現完成。有的web服務器應用程序為每個用戶請求生成一個進程或線程來進行響應,不過,一旦並發請求數量達到成千上萬時,讀個同時運行的進程或線程將會消耗大量的系統資源。

 

  3、I/O多路復用Web服務器

  為了能夠支持更多的並發用戶請求,越來越多的Web服務器正在采用多路復用的架構——同步監控所有連接請求的活動狀態,當一個連接的狀態正在發生改變時(如數據庫准備完畢或發生某錯誤時),將為其執行一系列特定操作;在操作完成后,此連接將重新變回暫時的穩定態並返回至打開的連接列表中,直到下一次的狀態改變。由於其多路復用的特性,進程或線程不會被空閑的連接所占用,因而可以提供高效的工作模式。

 

  4、多路復用多線程Web服務器

  將多進程和多多路復用的功能結合起來的Web服務器架構,其避免了讓一個進程服務於過多的用戶請求,並能充分利用多CPU主機所提供的計算能力。

 

小結:

Web服務器是一種C/S架構的模型:

  C:Client Agent(著名的有Browser,其它的還有reboot、spider)

  S:Server

  Client --> request(Client發起request報文請求) --> Server

    客戶端請求的資源靠URL標記,請求的資源通過報文首部向服務器傳遞。

  Server --> response(Server構建response報文給客戶端) --> Client

 

資源的獲取有不同的方法,稱為HTTP Method

  GET、HEAD、POST、DELETE、PUT、TRACE、OPTIONS、CONNECTION(前三個最常用)

 

請求的資源的狀態碼:

  為了明確表明客戶端請求哪個資源、哪個主機上的資源、資源類型,需要HTTP Headers,格式:

    NAME:VALUE

    Host:www.test.com

    Connection:keep-alive

 

服務器的主要工作:

 

Server響應模型:

  單進程/單線程;

  多進程/多線程;

  單進程/多請求;

  多進程/多請求;

 

http提供了多種響應模型(稱為httpd的MPM):

  prefork

  worker

  event

 

常用的客戶端瀏覽器:

  IE

  Firefox

  Chrome

  Opera

  Safari

 

常用的Server:  

  Apache的httpd

  IIS(不僅是純粹意義上的Web服務器還是應用程序服務器,能結合.net解析asp、asp.net等動態腳本)

  Nginx

  lighttpd(德國開發的開源軟件)

  thttpd(嵌入式用到的)

 

應用程序服務器:(都能提供Web服務,但並不是純粹意義上的Web服務器)

  IIS

  Tomcat(Apache的開源(Open Source)的,解析JSP)

  Websphere(IBM的(全球最牛的,Java企業級應用程序,解析JSP的,商業產品(commodity)))

  Weblogic(早期屬於Bea,后被Oracle收購(83億美元),解析JSP,商業產品(Commaodity))

  JBoss(當前屬於RedHat,分為開源版和商業版(買RedHat的服務),是重新封裝的Tomcat,在其基礎上做了更為豐富的包裝)

 

www.netcraft.com  此網站會每隔一段時間會統計一次全球互聯網上Web服務器各產品所占的比例。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM