亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

WSGI簡(jiǎn)介

Harpsichord1207 / 2009人閱讀

摘要:提出這些規(guī)范的目的就是為了定義統(tǒng)一的標(biāo)準(zhǔn),提升程序的可移植性。的對(duì)象處理完成后,會(huì)調(diào)用并且返回結(jié)果給,存放在中。比如可以檢查是否有非法內(nèi)容,檢查是否有非法內(nèi)容,為加上特定的等,這些都是可以的。的實(shí)現(xiàn)和部署要使用,需要分別實(shí)現(xiàn)角色和角色。

WSGI是什么

WSGI的全稱是Web Server Gateway Interface,翻譯過(guò)來(lái)就是Web服務(wù)器網(wǎng)關(guān)接口。具體的來(lái)說(shuō),WSGI是一個(gè)規(guī)范,定義了Web服務(wù)器如何與Python應(yīng)用程序進(jìn)行交互,使得使用Python寫(xiě)的Web應(yīng)用程序可以和Web服務(wù)器對(duì)接起來(lái)。WSGI一開(kāi)始是在PEP-0333中定義的,最新版本是在Python的PEP-3333定義的。

對(duì)于初學(xué)者來(lái)說(shuō),上面那段就是廢話,說(shuō)了跟沒(méi)說(shuō)一樣。本文的主要內(nèi)容就是說(shuō)清楚,WSGI到底是如何工作的。

為什么需要WSGI這個(gè)規(guī)范

在Web部署的方案上,有一個(gè)方案是目前應(yīng)用最廣泛的:

首先,部署一個(gè)Web服務(wù)器專門(mén)用來(lái)處理HTTP協(xié)議層面相關(guān)的事情,比如如何在一個(gè)物理機(jī)上提供多個(gè)不同的Web服務(wù)(單IP多域名,單IP多端口等)這種事情。

然后,部署一個(gè)用各種語(yǔ)言編寫(xiě)(Java, PHP, Python, Ruby等)的應(yīng)用程序,這個(gè)應(yīng)用程序會(huì)從Web服務(wù)器上接收客戶端的請(qǐng)求,處理完成后,再返回響應(yīng)給Web服務(wù)器,最后由Web服務(wù)器返回給客戶端。

那么,要采用這種方案,Web服務(wù)器和應(yīng)用程序之間就要知道如何進(jìn)行交互。為了定義Web服務(wù)器和應(yīng)用程序之間的交互過(guò)程,就形成了很多不同的規(guī)范。這種規(guī)范里最早的一個(gè)是CGI][3,1993年開(kāi)發(fā)的。后來(lái)又出現(xiàn)了很多這樣的規(guī)范。比如改進(jìn)CGI性能的FasgCGI,Java專用的Servlet規(guī)范,還有Python專用的WSGI規(guī)范等。提出這些規(guī)范的目的就是為了定義統(tǒng)一的標(biāo)準(zhǔn),提升程序的可移植性。在WSGI規(guī)范的最開(kāi)始的PEP-333中一開(kāi)始就描述了為什么需要WSGI規(guī)范。

WSGI如何工作

從上文可以知道,WSGI相當(dāng)于是Web服務(wù)器和Python應(yīng)用程序之間的橋梁。那么這個(gè)橋梁是如何工作的呢?首先,我們明確橋梁的作用,WSGI存在的目的有兩個(gè):

讓W(xué)eb服務(wù)器知道如何調(diào)用Python應(yīng)用程序,并且把用戶的請(qǐng)求告訴應(yīng)用程序。

讓Python應(yīng)用程序知道用戶的具體請(qǐng)求是什么,以及如何返回結(jié)果給Web服務(wù)器。

WSGI中的角色

在WSGI中定義了兩個(gè)角色,Web服務(wù)器端稱為server或者gateway,應(yīng)用程序端稱為application或者framework(因?yàn)閃SGI的應(yīng)用程序端的規(guī)范一般都是由具體的框架來(lái)實(shí)現(xiàn)的)。我們下面統(tǒng)一使用server和application這兩個(gè)術(shù)語(yǔ)。

server端會(huì)先收到用戶的請(qǐng)求,然后會(huì)根據(jù)規(guī)范的要求調(diào)用application端,如下圖所示:

調(diào)用的結(jié)果會(huì)被封裝成HTTP響應(yīng)后再發(fā)送給客戶端。

server如何調(diào)用application

首先,每個(gè)application的入口只有一個(gè),也就是所有的客戶端請(qǐng)求都同一個(gè)入口進(jìn)入到應(yīng)用程序。

接下來(lái),server端需要知道去哪里找application的入口。這個(gè)需要在server端指定一個(gè)Python模塊,也就是Python應(yīng)用中的一個(gè)文件,并且這個(gè)模塊中需要包含一個(gè)名稱為application的可調(diào)用對(duì)象(函數(shù)和類都可以),這個(gè)application對(duì)象就是這個(gè)應(yīng)用程序的唯一入口了。WSGI還定義了application對(duì)象的形式:

def simple_app(environ, start_response):
      pass

上面代碼中的environstart_response就是server端調(diào)用application對(duì)象時(shí)傳遞的兩個(gè)參數(shù)。

我們來(lái)看具體的例子。假設(shè)我們的應(yīng)用程序的入口文件是/var/www/index.py,那么我們就需要在server端配置好這個(gè)路徑(如何配置取決于server端的實(shí)現(xiàn)),然后在index.py中的代碼如下所示:

使用標(biāo)準(zhǔn)庫(kù)(這個(gè)只是demo)

import wsgiref

application = wsgiref.simple_server.demo_app

使用web.py框架

import web

urls = (
    "/.*", "hello",
)

class hello(object):
    def GET(self):
        return "Hello, world."

application = web.application(urls, globals()).wsgifunc()

你可以看到,文件中都需要有一個(gè)application對(duì)象,server端會(huì)找到這個(gè)文件,然后調(diào)用這個(gè)對(duì)象。所以支持WSGI的Python框架最終都會(huì)有這么一個(gè)application對(duì)象,不過(guò)框架的使用者不需要關(guān)心這個(gè)application對(duì)象內(nèi)部是如何工作的,只需要關(guān)心路由定義、請(qǐng)求處理等具體的業(yè)務(wù)邏輯。

因?yàn)閍pplication對(duì)象是唯一的入口,所以不管客戶端請(qǐng)求的路徑和數(shù)據(jù)是什么,server都是調(diào)用這個(gè)application對(duì)象,具體的客戶端請(qǐng)求的處理有application對(duì)象完成。

application對(duì)象需要做什么

上面已經(jīng)提到了,application對(duì)象需要是一個(gè)可調(diào)用對(duì)象,而且其定義需要滿足如下形式:

def simple_app(environ, start_response):
      pass

當(dāng)server按照WSGI的規(guī)范調(diào)用了application之后,application就可以開(kāi)始處理客戶端的請(qǐng)求了,處理請(qǐng)求之后,application對(duì)象需要返回處理結(jié)果給server端。處理請(qǐng)求和返回結(jié)果這兩個(gè)事情,都和server調(diào)用application對(duì)象時(shí)傳遞的兩個(gè)參數(shù)有關(guān)。

environ參數(shù)

environ參數(shù)是一個(gè)Python的字典,里面存放了所有和客戶端相關(guān)的信息,這樣application對(duì)象就能知道客戶端請(qǐng)求的資源是什么,請(qǐng)求中帶了什么數(shù)據(jù)等。environ字典包含了一些CGI規(guī)范要求的數(shù)據(jù),以及WSGI規(guī)范新增的數(shù)據(jù),還可能包含一些操作系統(tǒng)的環(huán)境變量以及Web服務(wù)器相關(guān)的環(huán)境變量。我們來(lái)看一些environ中常用的成員:

首先是CGI規(guī)范中要求的變量:

REQUEST_METHOD: 請(qǐng)求方法,是個(gè)字符串,"GET", "POST"等

SCRIPT_NAME: HTTP請(qǐng)求的path中的用于查找到application對(duì)象的部分,比如Web服務(wù)器可以根據(jù)path的一部分來(lái)決定請(qǐng)求由哪個(gè)virtual host處理

PATH_INFO: HTTP請(qǐng)求的path中剩余的部分,也就是application要處理的部分

QUERY_STRING: HTTP請(qǐng)求中的查詢字符串,URL中?后面的內(nèi)容

CONTENT_TYPE: HTTP headers中的content-type內(nèi)容

CONTENT_LENGTH: HTTP headers中的content-length內(nèi)容

SERVER_NAMESERVER_PORT: 服務(wù)器名和端口,這兩個(gè)值和前面的SCRIPT_NAME, PATH_INFO拼起來(lái)可以得到完整的URL路徑

SERVER_PROTOCOL: HTTP協(xié)議版本,HTTP/1.0或者HTTP/1.1

HTTP_: 和HTTP請(qǐng)求中的headers對(duì)應(yīng)。

WSGI規(guī)范中還要求environ包含下列成員:

wsgi.version:表示W(wǎng)SGI版本,一個(gè)元組(1, 0),表示版本1.0

wsgi.url_scheme:http或者h(yuǎn)ttps

wsgi.input:一個(gè)類文件的輸入流,application可以通過(guò)這個(gè)獲取HTTP request body

wsgi.errors:一個(gè)輸出流,當(dāng)應(yīng)用程序出錯(cuò)時(shí),可以將錯(cuò)誤信息寫(xiě)入這里

wsgi.multithread:當(dāng)application對(duì)象可能被多個(gè)線程同時(shí)調(diào)用時(shí),這個(gè)值需要為T(mén)rue

wsgi.multiprocess:當(dāng)application對(duì)象可能被多個(gè)進(jìn)程同時(shí)調(diào)用時(shí),這個(gè)值需要為T(mén)rue

wsgi.run_once:當(dāng)server期望application對(duì)象在進(jìn)程的生命周期內(nèi)只被調(diào)用一次時(shí),該值為T(mén)rue

上面列出的這些內(nèi)容已經(jīng)包括了客戶端請(qǐng)求的所有數(shù)據(jù),足夠application對(duì)象處理客戶端請(qǐng)求了。

start_resposne參數(shù)

start_response是一個(gè)可調(diào)用對(duì)象,接收兩個(gè)必選參數(shù)和一個(gè)可選參數(shù):

status: 一個(gè)字符串,表示HTTP響應(yīng)狀態(tài)字符串

response_headers: 一個(gè)列表,包含有如下形式的元組:(header_name, header_value),用來(lái)表示HTTP響應(yīng)的headers

exc_info(可選): 用于出錯(cuò)時(shí),server需要返回給瀏覽器的信息

當(dāng)application對(duì)象根據(jù)environ參數(shù)的內(nèi)容執(zhí)行完業(yè)務(wù)邏輯后,就需要返回結(jié)果給server端。我們知道HTTP的響應(yīng)需要包含status,headers和body,所以在application對(duì)象將body作為返回值return之前,需要先調(diào)用start_response(),將status和headers的內(nèi)容返回給server,這同時(shí)也是告訴server,application對(duì)象要開(kāi)始返回body了。

application對(duì)象的返回值

application對(duì)象的返回值用于為HTTP響應(yīng)提供body,如果沒(méi)有body,那么可以返回None。如果有body的化,那么需要返回一個(gè)可迭代的對(duì)象。server端通過(guò)遍歷這個(gè)可迭代對(duì)象可以獲得body的全部?jī)?nèi)容。

application demo

PEP-3333中有一個(gè)application的實(shí)現(xiàn)demo,我把它再簡(jiǎn)化之后如下:

def simple_app(environ, start_response):
      status = "200 OK"
      response_headers = [("Content-type", "text/plain")]
      start_response(status, response_headers)
      return ["hello, world"]

可以將這段代碼和前面的說(shuō)明對(duì)照起來(lái)理解。

再談server如何調(diào)用application

前面已經(jīng)知道server如何定位到application的入口了,也知道了application的入口的形式以及application對(duì)象內(nèi)部需要完成的工作。那么,我們還需要再說(shuō)一下,environstart_response()是需要在server端的生成和定義的,其中關(guān)于start_response()的部分在規(guī)范中也有明確的要求。這部分內(nèi)容太長(zhǎng)了,不適合放在本文中,有興趣的讀者可以去看下PEP-3333,里面有一段server端的demo實(shí)現(xiàn)。

WSGI中間件

WSGI Middleware(中間件)也是WSGI規(guī)范的一部分。上一章我們已經(jīng)說(shuō)明了WSGI的兩個(gè)角色:server和application。那么middleware是一種運(yùn)行在server和application中間的應(yīng)用(一般都是Python應(yīng)用)。middleware同時(shí)具備server和application角色,對(duì)于server來(lái)說(shuō),它是一個(gè)application;對(duì)于application來(lái)說(shuō),它是一個(gè)server。middleware并不修改server端和application端的規(guī)范,只是同時(shí)實(shí)現(xiàn)了這兩個(gè)角色的功能而已。

我們可以通過(guò)下圖來(lái)說(shuō)明middleware是如何工作的:

上圖中最上面的三個(gè)彩色框表示角色,中間的白色框表示操作,操作的發(fā)生順序按照1 ~ 5進(jìn)行了排序,我們直接對(duì)著上圖來(lái)說(shuō)明middleware是如何工作的:

Server收到客戶端的HTTP請(qǐng)求后,生成了environ_s,并且已經(jīng)定義了start_response_s。

Server調(diào)用Middleware的application對(duì)象,傳遞的參數(shù)是environ_sstart_response_s。

Middleware會(huì)根據(jù)environ執(zhí)行業(yè)務(wù)邏輯,生成environ_m,并且已經(jīng)定義了start_response_m。

Middleware決定調(diào)用Application的application對(duì)象,傳遞參數(shù)是environ_mstart_response_m。Application的application對(duì)象處理完成后,會(huì)調(diào)用start_response_m并且返回結(jié)果給Middleware,存放在result_m中。

Middleware處理result_m,然后生成result_s,接著調(diào)用start_response_s,并返回結(jié)果result_s給Server端。Server端獲取到result_s后就可以發(fā)送結(jié)果給客戶端了。

從上面的流程可以看出middleware應(yīng)用的幾個(gè)特點(diǎn):

Server認(rèn)為middleware是一個(gè)application。

Application認(rèn)為middleware是一個(gè)server。

Middleware可以有多層。

因?yàn)镸iddleware能過(guò)處理所有經(jīng)過(guò)的request和response,所以要做什么都可以,沒(méi)有限制。比如可以檢查request是否有非法內(nèi)容,檢查response是否有非法內(nèi)容,為request加上特定的HTTP header等,這些都是可以的。

WSGI的實(shí)現(xiàn)和部署

要使用WSGI,需要分別實(shí)現(xiàn)server角色和application角色。

Application端的實(shí)現(xiàn)一般是由Python的各種框架來(lái)實(shí)現(xiàn)的,比如Django, web.py等,一般開(kāi)發(fā)者不需要關(guān)心WSGI的實(shí)現(xiàn),框架會(huì)會(huì)提供接口讓開(kāi)發(fā)者獲取HTTP請(qǐng)求的內(nèi)容以及發(fā)送HTTP響應(yīng)。

Server端的實(shí)現(xiàn)會(huì)比較復(fù)雜一點(diǎn),這個(gè)主要是因?yàn)檐浖軜?gòu)的原因。一般常用的Web服務(wù)器,如Apache和nginx,都不會(huì)內(nèi)置WSGI的支持,而是通過(guò)擴(kuò)展來(lái)完成。比如Apache服務(wù)器,會(huì)通過(guò)擴(kuò)展模塊mod_wsgi來(lái)支持WSGI。Apache和mod_wsgi之間通過(guò)程序內(nèi)部接口傳遞信息,mod_wsgi會(huì)實(shí)現(xiàn)WSGI的server端、進(jìn)程管理以及對(duì)application的調(diào)用。Nginx上一般是用proxy的方式,用nginx的協(xié)議將請(qǐng)求封裝好,發(fā)送給應(yīng)用服務(wù)器,比如uWSGI,應(yīng)用服務(wù)器會(huì)實(shí)現(xiàn)WSGI的服務(wù)端、進(jìn)程管理以及對(duì)application的調(diào)用。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/37580.html

相關(guān)文章

  • flask 源碼解析:簡(jiǎn)介

    摘要:簡(jiǎn)介官網(wǎng)上對(duì)它的定位是一個(gè)微開(kāi)發(fā)框架。另外一個(gè)必須理解的概念是,簡(jiǎn)單來(lái)說(shuō)就是一套和框架應(yīng)用之間的協(xié)議。功能比較豐富,支持解析自動(dòng)防止攻擊繼承變量過(guò)濾器流程邏輯支持代碼邏輯集成等等。那么,從下一篇文章,我們就正式開(kāi)始源碼之旅了 文章屬于作者原創(chuàng),原文發(fā)布在個(gè)人博客。 flask 簡(jiǎn)介 Flask 官網(wǎng)上對(duì)它的定位是一個(gè)微 python web 開(kāi)發(fā)框架。 Flask is a micro...

    megatron 評(píng)論0 收藏0
  • 通過(guò)demo學(xué)習(xí)OpenStack開(kāi)發(fā)所需的基礎(chǔ)知識(shí) -- API服務(wù)(2)

    摘要:這種表示具體的。中其他的關(guān)鍵字則是函數(shù)的參數(shù),用于表示不同的前綴。這個(gè)是這個(gè)指定的第一個(gè),作用是限制請(qǐng)求的大小。表示實(shí)現(xiàn)主要功能的應(yīng)用,是一個(gè)標(biāo)準(zhǔn)的。對(duì)象是根據(jù)中的配置來(lái)處理的。最后會(huì)把請(qǐng)求交給進(jìn)行處理。 本文會(huì)重點(diǎn)講解OpenStack中使用的API開(kāi)發(fā)框架的使用。但是本文的目的并不是覆蓋這些框架的使用細(xì)節(jié),而是通過(guò)說(shuō)明重要的部分,降低初學(xué)者的入門(mén)的門(mén)檻。框架的使用細(xì)節(jié)都可以從文檔中...

    Martin91 評(píng)論0 收藏0
  • [轉(zhuǎn)]深入理解wsgiref

    摘要:原地址介紹要很好地理解下面的代碼,最好有一定的編程基礎(chǔ),了解的基本概念和流程。這個(gè)文件主要是的處理過(guò)程,定義調(diào)用處理等等。 原地址:http://cizixs.com/2014/11/09/... 1. 介紹 要很好地理解下面的代碼,最好有一定的 socket 編程基礎(chǔ),了解 socket 的基本概念和流程。 wsgiref 是 PEP 333 定義的 wsgi 規(guī)范的范例實(shí)現(xiàn),里面...

    Moxmi 評(píng)論0 收藏0
  • 通過(guò)demo學(xué)習(xí)OpenStack開(kāi)發(fā)所需的基礎(chǔ)知識(shí) -- API服務(wù)(1)

    摘要:通過(guò),也就是通過(guò)各個(gè)項(xiàng)目提供的來(lái)使用各個(gè)服務(wù)的功能。通過(guò)使用的方式是由各個(gè)服務(wù)自己實(shí)現(xiàn)的,比如負(fù)責(zé)計(jì)算的項(xiàng)目實(shí)現(xiàn)了計(jì)算相關(guān)的,負(fù)責(zé)認(rèn)證的項(xiàng)目實(shí)現(xiàn)了認(rèn)證和授權(quán)相關(guān)的。的服務(wù)都是使用的方式來(lái)部署的。 使用OpenStack服務(wù)的方式 OpenStack項(xiàng)目作為一個(gè)IaaS平臺(tái),提供了三種使用方式: 通過(guò)Web界面,也就是通過(guò)Dashboard(面板)來(lái)使用平臺(tái)上的功能。 通過(guò)命令行,也就...

    Jason_Geng 評(píng)論0 收藏0
  • Django學(xué)習(xí)——Django的基礎(chǔ)2(安裝、簡(jiǎn)介

    摘要:安裝安裝版本可以在和之前的版本可以使用,可以安裝之后的版本我在這里安裝的是版本驗(yàn)證是否安裝成功如何創(chuàng)建一個(gè)項(xiàng)目創(chuàng)建項(xiàng)目創(chuàng)建項(xiàng)目目錄目錄名稱目錄名稱我在此創(chuàng)建目錄然后進(jìn)入該目錄。 安裝 pip install django==1.11.4 安裝1.11版本可以在python2 和python3.6之前的版本可以使用,python3.7可以安裝2.0之后的版本我在這里安裝的是2.1.7版本...

    oysun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<