瞭解了HTTP協議和HTML文檔,咱們其實就明白了一個Web應用的本質就是:html
1.瀏覽器發送一個HTTP請求; 2.服務器收到請求,生成一個HTML文檔; 3.服務器把HTML文檔做爲HTTP響應的Body發送給瀏覽器; 4.瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。
因此,最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。Apache、Nginx、Lighttpd等這些常見的靜態服務器就是幹這件事情的。python
若是要動態生成HTML,就須要把上述步驟本身來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,若是咱們本身來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。web
正確的作法是底層代碼由專門的服務器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP原始請求和響應格式,因此,須要一個統一的接口,讓咱們專心用Python編寫Web業務。瀏覽器
這個接口就是WSGI:Web Server Gateway Interface。bash
WSGI是Web 服務器(uWSGI)與 Web 應用程序或應用框架(Django)之間的一種低級別的接口
WSGI:全稱是Web Server Gateway Interface,WSGI不是服務器,python模塊,框架,API或者任何軟件,只是一種規範,描述web server如何與web application通訊的規範。server和application的規範在PEP 3333中有具體描述。要實現WSGI協議,必須同時實現web server和web application,當前運行在WSGI協議之上的web框架有Torando,Flask,Django服務器
uwsgi:與WSGI同樣是一種通訊協議,是uWSGI服務器的獨佔協議,用於定義傳輸信息的類型(type of information),每個uwsgi packet前4byte爲傳輸信息類型的描述,與WSGI協議是兩種東西,聽說該協議是fcgi協議的10倍快。app
uWSGI:是一個web服務器,實現了WSGI協議、uwsgi協議、http協議等。框架
WSGI協議主要包括server和application兩部分:webapp
WSGI server負責從客戶端接收請求,將request轉發給application,將application返回的response返回給客戶端;
WSGI application接收由server轉發的request,處理請求,並將處理結果返回給server。application中能夠包括多個棧式的中間件(middlewares),這些中間件須要同時實現server與application,所以能夠在WSGI服務器與WSGI應用之間起調節做用:對服務器來講,中間件扮演應用程序,對應用程序來講,中間件扮演服務器。
WSGI協議實際上是定義了一種server與application解耦的規範,便可以有多個實現WSGI server的服務器,也能夠有多個實現WSGI application的框架,那麼就能夠選擇任意的server和application組合實現本身的web應用。例如uWSGI和Gunicorn都是實現了WSGI server協議的服務器,Django,Flask是實現了WSGI application協議的web框架,能夠根據項目實際狀況搭配使用函數
WSGI規範以下:
在Python標準庫中,wsgiref包就是符合WSGI標準的Web服務實現。後面簡單對wsgiref包進行介紹,以此來對符合WSGI標準的Web服務的實現過程進行梳理。
WSGI接口定義很是簡單,它只要求Web開發者實現一個函數,就能夠響應HTTP請求。咱們來看一個最簡單的Web版本的「Hello, web!」:
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'<h1>Hello, web!</h1>']
而後,再編寫一個server.py
,負責啓動WSGI服務器,加載application()
函數:
# server.py # 從wsgiref模塊導入: from wsgiref.simple_server import make_server # 導入咱們本身編寫的application函數: from hello import application # 建立一個服務器,IP地址爲空,端口是8000,處理函數是application: httpd = make_server('', 8000, application) print('Serving HTTP on port 8000...') # 開始監聽HTTP請求: httpd.serve_forever()
不管多麼複雜的Web應用程序,入口都是一個WSGI處理函數。HTTP請求的全部輸入信息均可以經過environ
得到,HTTP響應的輸出均可以經過start_response()
加上函數返回值做爲Body。
複雜的Web應用程序,光靠一個WSGI函數來處理仍是太底層了,咱們須要在WSGI之上再抽象出Web框架,進一步簡化Web開發。
參考資料
http://python.jobbole.com/88637/
http://python.jobbole.com/88653/
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432012393132788f71e0edad4676a3f76ac7776f3a16000