網關協議

目錄

一 靜態頁面和動態頁面

二 什麼是web server

三 什麼是網關協議

3.1 引子

3.2 網關協議

四 網關協議CGI、FastCGI、WSGI、UWSGI

五 網關協議與keystone

六 概念梳理


一 靜態頁面和動態頁面


在瞭解了http協議後,我們知曉,一個web server的本質就是


瀏覽器發送一個HTTP請求;


服務器收到請求,生成一個HTML文檔;


服務器把HTML文檔作爲HTTP響應的Body發送給瀏覽器;


瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。


而用戶的請求的結果分靜態頁面和動態頁面兩種


靜態頁面:是一對寫死了的html代碼,所有的訪問者看到的內容都一樣,如你訪問京東的主頁,所有人看到的都一樣


動態頁面:動態的概念意味着變,程序中體現'變'的概念就是變量,因而在html代碼中需要嵌入變量,變量的值的來源需要用一段代碼動態生成,這樣不同的用戶會提交不同的數據給服務端,服務端分析用戶提交過來的數據然後執行這段代碼,動態生成值後賦值html中變量,然後返回html給用戶,這樣對每個用戶來說收到的頁面都是不一樣的。比如你登錄京東,登錄後返回的頁面每個人都不一樣。


 

二 什麼是web server


用戶上網的本質就是在自己這端啓動socket client(瀏覽器),服務的啓動socket server(web server)。


基於http協議的學習我們知道,web server主要是用來響應用戶的http請求然後返回html頁面給用戶。


從用戶上網的角度來說,早期的互聯網只有倆個角色:瀏覽器<->web server,此時所有的用戶訪問的都是靜態頁面


現在主流的web server有apache,nginx,lighttpd等,須知,它們只能接收用戶的請求然後生成靜態頁面


 

三 什麼是網關協議


 

3.1 引子


隨着互聯網的發展,網站爲每個用戶單獨定製個人的東西呈現給用戶成爲了主流,這時候就產生了動態頁面的需求。


因web server比如apache只能處理靜態請求,所以對於動態請求,你需要編寫專門的程序來處理

1036857-20170110122807463-826130772.png

隨着互聯網的發展,越來越多的用戶數據需要永久保存下來,文件是可以永久保存,但是文件的數據處理性能太低,於是數據庫慢慢成爲了網站大後端的主流

1036857-20170110123449275-382905183.png


apache無法處理動態請求,所以我們需要自己編寫一個個的功能來處理這些動態請求(注意:這些動態請求有的需要查詢數據庫有的則不需要)


我們按照一個需要操作數據的動態請求舉例,來分析下問題



#處理動態請求的僞代碼,可以稱之爲web application,或者簡web app


一:接收apache提交過來的用戶請求,觸發函數運行

二:連接數據庫

三:操作數據庫(增刪改查)

四:根據獲取的數據進行其他邏輯處理

五:返回給apache數據

六:關閉數據庫


問題一:


你在編寫web app時,需要深入研究apache工作的協議HTTP,等你研究明白了,過去了一百年。這嚴重影響了開發效率。


問題二:


這只是你針對apache這款web server定製的代碼,換成了另外的web server你的程序無法重用


問題三:


這只是針對一種動態請求的代碼實現,對於其他的動態請求呢,你仍然需要寫重複的代碼去處理。


3.2 網關協議

1036857-20170110125014635-253599833.png


如何解決問題一:


我們迫切需要在web server與web app之間定義一種標準,用來明細分工,web server對外提供一種標準,web app開發者只要遵循這個標準,那麼後者就無需考慮web server到底是如何實現的了而可以專注web app的開發,這個標準就是網關協議


如何解決問題二:


在web server與web app之間定義了標準,那麼只要我的web app是遵循這個標準的,換另外一個也遵循該標準的web server,同樣可以運行


如何解決問題三:


這裏需要引入一個概念叫:web app開發框架(也稱web 框架)


web app開發框架用來爲web app開發者提供一套現成的開發工具與開發模式,web app開發者不再需要寫重複代碼了,只需要使用某種現成的web開發框架,一些重複的功能就不用再去重複造輪子了,這極大的提高了開發效率


比如web app開發框架一般本事都是基於網關協議標準實現的,因爲你用web app開發框架去開發web app,自然就是遵循某種網關協議標準的,你甚至連這個協議具體是什麼都無需知道。



四 網關協議CGI、FastCGI、WSGI、UWSGI


網關協議CGI


什麼是CGI?


CGI即通用網關接口(Common Gateway Interface),是web app應用程序(CGI程序)與Web服務器之間的接口標準。。


CGI 的跨平臺性能極佳,幾乎可以在任何操作系統上實現。


fork-and-execute模式:apache接收用戶動態請求,先要創建cgi的子進程,然後處理請求,處理完後結束這個子進程。


fork-and-execute模式的弊端:用cgi方式的服務器有多少連接請求就會有多少cgi子進程,子進程反覆加載是cgi性能低下的主要原因。當用戶請求數量非常多時,會大量擠佔系統的資源如內存,CPU時間等,造成效能低下。


CGI腳本的工作流程:


瀏覽器發送動態請求(通過HTML表單或者超鏈接)

服務端接收該請求,調用CGI腳本,產生一個CGI進程來處理該動態請求,結果返回給服務器

服務器將html返回給瀏覽器

網關協議FASTCGI


什麼是FASTCGI?


FastCGI是從CGI發展改進而來的


傳統CGI接口方式的主要缺點是性能很差,因爲每次HTTP服務器遇到動態請求時都需要重新啓動腳本解析器來處理,然後返回結果給HTTP服務器。無法應對高並非場景。


FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。


CGI 就是所謂的短生存期應用程序,FastCGI 就是所謂的長生存期應用程序。


由於 FastCGI 程序並不需要不斷的產生新進程,可以大大降低服務器的壓力並且產生較高的應用效率。它的速度效率最少要比CGI 技術提高 5 倍以上。它還支持分佈式的運算, 即 FastCGI 程序可以在網站服務器以外的主機上執行並且接受來自其它網站服務器來的請求。


 


FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並因此獲得較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要原因,如果CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則可以提供良好的性能、伸縮性、Fail-Over特性等等。FastCGI接口方式採用C/S結構,可以將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啓動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然後將得到的結果返回給瀏覽器。這種方式可以讓HTTP服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。


FastCGI的工作流程:


Web Server啓動時載入FastCGI進程管理器(PHP-CGI或者PHP-FPM或者spawn-cgi)

FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的連接。

當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。

FastCGI子進程完成處理後將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個連接。 在CGI模式中,php-cgi在此便退出。

FastCGI 的特點


打破傳統頁面處理技術。傳統的頁面處理技術,程序必須與 Web 服務器或 Application 服務器處於同一臺服務器中。這種歷史已經早N年被FastCGI技術所打破,FastCGI技術的應用程序可以被安裝在服務器羣中的任何一臺服務器,而通過 TCP/IP 協議與 Web 服務器通訊,這樣做既適合開發大型分佈式 Web 羣,也適合高效數據庫控制。

明確的請求模式。CGI 技術沒有一個明確的角色,在 FastCGI 程序中,程序被賦予明確的角色(響應器角色、認證器角色、過濾器角色)。




PHP-CGI是PHP自帶的FastCGI管理器。PHP-CGI的不足:


php-cgi變更php.ini配置後需重啓php-cgi才能讓新的php-ini生效,不可以平滑重啓

直接殺死php-cgi進程php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑從新生成新的子進程。)


Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,很多人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工作,不過有不少缺點。而PHP-FPM的出現多少緩解了一些問題,但PHP-FPM有個缺點就是要重新編譯,這對於一些已經運行的環境可能有不小的風險),在php 5.3.3中可以直接使用PHP-FPM了。Spawn-FCGI的代碼很少,全部才630行,用c語言編寫,最近一次提交是5年前。代碼主頁:https://github.com/lighttpd/spawn-fcgi


Spawn-FCGI代碼分析如下:


spawn-fcgi 首先create socket,bind,listen 3步創建服務器socket,(把這個socket叫做 fcgi_fd)

用dup2,把fcgi_fd 交換給 FCGI_LISTENSOCK_FILENO (FCGI_LISTENSOCK_FILENO數值上等於0,這是fastcgi協議當中指定用來listen的socket id)

執行execl ,replaces the current process image with a new process image. process image 進程在運行空間的代碼段

很顯然,Spawn-FCGI也是 pre-fork 模型,只是用了上古C語言編寫,充滿了N多 unix下暗黑編程技巧。


Spawn-FCGI功能很單一:


只管fork進程,子進程掛了,主進程僅僅log記錄一次,根本不會重新fork。在2009年一段時間內,我曾經用spawn-fcgi部署php-cgi,當跑一段時間就會全掛掉,只能用crontab定時重啓spawn-fcgi

不負責子進程中的網絡IO,把socket放到指定位置就完了,接下來的事情由被spawn的程序處理

Spawn-FCGI是一個很早期的程序,瞻仰一下即可。另外有:1996年的一段代碼:

http://www.fastcgi.com/om_archive/kit/cgi-fcgi/cgi-fcgi.c

和spawn-fcgi一個風格



PHP-FPM是一個PHP FastCGI管理器,是隻用於PHP的,可以在 http://php-fpm.org/download下載得到。PHP-FPM其實是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後纔可以使用。FPM(FastCGI 進程管理器)用於替換 PHP-CGI 的大部分附加功能,對於高負載網站是非常有用的。它的功能包括:


支持平滑停止/啓動的高級進程管理功能;

可以工作於不同的 uid/gid/chroot 環境下,並監聽不同的端口和使用不同的 php.ini 配置文件(可取代 safe_mode 的設置);

stdout 和 stderr 日誌記錄;

在發生意外情況的時候能夠重新啓動並緩存被破壞的 opcode;

文件上傳優化支持;

“慢日誌” – 記錄腳本(不僅記錄文件名,還記錄 PHP backtrace 信息,可以使用 ptrace或者類似工具讀取和分析遠程進程的運行數據)運行所導致的異常緩慢;

fastcgi_finish_request() – 特殊功能:用於在請求完成和刷新數據後,繼續在後臺執行耗時的工作(錄入視頻轉換、統計處理等);

動態/靜態子進程產生;

基本 SAPI 運行狀態信息(類似Apache的 mod_status);

基於 php.ini 的配置文件。




網關協議WSGI


什麼是WSGI?


Web服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)是爲Python語言定義的Web服務器和Web應用程序或框架之間的一種簡單而通用的接口。它只是一個接口定義:它不負責服務器的實現,也不負責網頁應用的實現,它只是一個兩邊接口方式的約定。


自從WSGI被開發出來以後,許多其它語言中也出現了類似接口。WSGI是作爲Web服務器與Web應用程序或應用框架之間的一種低級別的接口,以提升可移植Web應用開發的共同點。WSGI是基於現存的CGI標準而設計的。WSGI就是Python的CGI包裝,相對於Fastcgi是PHP的CGI包裝


有了WSGI,你就不用去考慮,服務器程序的具體實現,應用程序獲得了很好的適用性。比如一個雲平臺提供了對 WSGI 接口的支持,那麼,只要應用是基於 WSGI 的,就可以直接跑起來。其實keystone就是一款python開發的基於WSGI標準的app。


什麼是WSGI中間件?


基於WSGI 的設計哲學,我們可以寫一些對 server 和 application 都兼容的模塊,即WSGI中間件(middleware)。所謂的 WSGI 中間件同時實現了API的兩方,因此可以在WSGI服務和WSGI應用之間起調解作用:從WSGI服務器的角度來說,中間件扮演應用程序,而從應用程序的角度來說,中間件扮演服務器。


WSGI中間件的功能與好處?


WSGI中間件可以完成比如緩存、字符編碼轉換、根據 url 做應用 routing 等功能。


這種設計模式,是 WSGI 降低了 server 和 application 耦合度之後的產物,同時,它從另一個角度大大提升了設計的靈活性。


WSGI的處理模式


WSGI將 web 組件分爲三類: web服務器,web中間件,web應用程序


wsgi基本處理模式爲 : WSGI Server -> (WSGI Middleware)* -> WSGI Application 。


在處理一個WSGI請求時,服務器會爲應用程序提供環境資訊及一個回呼函數(Callback Function)。當應用程序完成處理請求後,透過前述的回呼函數,將結果回傳給服務器。


 


1.WSGI Server/gateway


wsgi server可以理解爲一個符合wsgi規範的web server,接收request請求,封裝一系列環境變量,按照wsgi規範調用註冊的wsgi app,最後將response返回給客戶端。文字很難解釋清楚wsgi server到底是什麼東西,以及做些什麼事情,最直觀的方式還是看wsgi server的實現代碼。以python自帶的wsgiref爲例,wsgiref是按照wsgi規範實現的一個簡單wsgi server。

1036857-20170110152452463-1595427649.png

1.服務器創建socket,監聽端口,等待客戶端連接。

2.當有請求來時,服務器解析客戶端信息放到環境變量environ中,並調用綁定的handler來處理請求。

3.handler解析這個http請求,將請求信息例如method,path等放到environ中。

4.wsgi handler再將一些服務器端信息也放到environ中,最後服務器信息,客戶端信息,本次請求信息全部都保存到了環境變量environ中。

5.wsgi handler 調用註冊的wsgi app,並將environ和回調函數傳給wsgi app

6.wsgi app 將reponse header/status/body 回傳給wsgi handler

7.最終handler還是通過socket將response信息塞回給客戶端。



2、WSGI Application


wsgi application就是一個普通的callable對象,當有請求到來時,wsgi server會調用這個wsgi app。這個對象接收兩個參數,通常爲environ,start_response。environ就像前面介紹的,可以理解爲環境變量,跟一次請求相關的所有信息都保存在了這個環境變量中,包括服務器信息,客戶端信息,請求信息。start_response是一個callback函數,wsgi application通過調用start_response,將response headers/status 返回給wsgi server。此外這個wsgi app會return 一個iterator對象 ,這個iterator就是response body。


基於python wsgiref製作wsgi server(web server)



3、WSGI MiddleWare


有些功能可能介於服務器程序和應用程序之間,例如,服務器拿到了客戶端請求的URL, 不同的URL需要交由不同的函數處理,這個功能叫做 URL Routing,這個功能就可以放在二者中間實現,這個中間層就是 middleware。middleware對服務器程序和應用是透明的,也就是說,服務器程序以爲它就是應用程序,而應用程序以爲它就是服務器。這就告訴我們,middleware需要把自己僞裝成一個服務器,接受應用程序,調用它,同時middleware還需要把自己僞裝成一個應用程序,傳給服務器程序。


 

網關協議uWSGI


uWSGI is gaining steam as a highly-performant WSGI server implementation.


參考:


http://www.fullstackpython.com/wsgi-servers.html


https://www.biaodianfu.com/cgi-fastcgi-wsgi.html


http://www.cnblogs.com/pied/p/4597740.html


 

五 網關協議與keystone


keystone本質就是python開發的一款基於wsgi的app,社區提倡的部署方法:


apache(wsgi)+keystone


nginx(uwsgi)+keystone


 

六 概念梳理


客戶端


常用瀏覽器:chrome


web服務


常用web server:apache,nginx,lighttpd


web app


常用web app開發語言:python,php,java


python常用web app開發框架(Web框架):


除了Flask,常見的Python 還有:


Flask:輕量級Web app開發框架;


Django:全能型Web app開發框架;

web.py:一個小巧的Web app開發框架;


Bottle:和Flask類似的Web app開發框架;


Tornado:Facebook的開源異步Web app開發框架。


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