最近基于Django Web框架在開(kāi)發(fā)一個(gè)后端項(xiàng)目,在Web Server和Django應(yīng)用程序交互的過(guò)程中總會(huì)碰到本文題目提及到的幾個(gè)概念,筆者特意花了點(diǎn)時(shí)間研究了下,為方便以后溫習(xí)特在此記錄一下。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括韶關(guān)網(wǎng)站建設(shè)、韶關(guān)網(wǎng)站制作、韶關(guān)網(wǎng)頁(yè)制作以及韶關(guān)網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,韶關(guān)網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到韶關(guān)省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
英文全稱:Web Server Gateway Interface,Web服務(wù)網(wǎng)管接口,簡(jiǎn)單來(lái)說(shuō)它是一種Web服務(wù)器和應(yīng)用程序間的通信規(guī)范。
uwsgi是一種通信協(xié)議,不過(guò)跟WSGI分屬兩種東西,該協(xié)議下速度比較快。
uWSGI是一個(gè)Web Server,并且獨(dú)占uwsgi協(xié)議,但是同時(shí)支持WSGI協(xié)議、HTTP協(xié)議等,它的功能是把HTTP協(xié)議轉(zhuǎn)化成語(yǔ)言支持的網(wǎng)絡(luò)協(xié)議供python使用。
在做Django項(xiàng)目時(shí),一般測(cè)試開(kāi)發(fā)我們直接用Django內(nèi)嵌的Web Server即可,但是如果項(xiàng)目要上生產(chǎn)環(huán)境,考慮并發(fā)等性能時(shí),我們可能需要uwsgi和nginx,下面只說(shuō)明uwsgi的常用用法,至于nginx的配置筆者后續(xù)準(zhǔn)備專門(mén)寫(xiě)一篇博文來(lái)講。
uwsgi執(zhí)行一般有兩種方式:命令行和文件配置,但是命令行可能需要識(shí)記很多參數(shù),因此采用文件配置是更通用的做法,文件格式支持很多種比如ini、xml、yaml等,筆者建議還是采用比較簡(jiǎn)單key-value形式ini模式,下面給出一個(gè)簡(jiǎn)單的uwsgi ini配置實(shí)例:
執(zhí)行:uwsgi --ini /path/to/uwsgi.ini
參數(shù)解釋:
更多uwsgi參數(shù)可參考官方文檔:
如何部署Golang應(yīng)用
安裝supervisord
# 通過(guò)載入程式 ez_setup.py 來(lái)安裝。這個(gè)載入程式會(huì)聯(lián)網(wǎng)下載最新版本setuptools來(lái)安裝,同時(shí)也可以更新本地的setuptools。
wget :peak.telemunity./dist/ez_setup.py
sudo python ez_setup.py
# 更新setuptools:
sudo python ez_setup.py -U setuptools
# 安裝supervisor
easy_install supervisor
# 生成配置檔案
echo_supervisord_conf /etc/supervisord.conf
# 編輯配置檔案
vim /etc/supervisord.conf
# 進(jìn)入vim后找到最后兩行,開(kāi)啟注釋(取消前面的分號(hào)),
# [include]
# files = supervisor.d/*.ini
# 將所有的supervisor配置都放到 /etc/supervisor.d目錄
mkdir /etc/supervisor.d
建立 supervisor 對(duì)應(yīng)程式的配置檔案
其中的一些路徑需要換成自己對(duì)應(yīng)的,這里將 zankbo 這個(gè)web 應(yīng)用放在了對(duì)應(yīng)的使用者目錄下
通過(guò)在生產(chǎn)伺服器上設(shè)定environment可以在程式里判斷是線上還是開(kāi)發(fā)模式,如 zankbo 的 debug判斷
當(dāng)然也可已在啟動(dòng)命令處加入引數(shù),如 mand = /home/zankbo/gopath/src/zankbo/zankbo -d 來(lái)關(guān)閉Debug模式。
if os.Getenv("APP_NAME") == "ZANKBO_PRODUCT" {
beego.RunMode = "prod"
}
vim /etc/supervisor.d/zankbo.ini
# 寫(xiě)入
[program:zankbo]
directory = /home/zankbo/gopath/src/zankbo
environment=APP_NAME="ZANKBO_PRODUCT"
mand = /home/zankbo/gopath/src/zankbo/zankbo
autostart = true
startsecs = 5
user = zankbo
redirect_stderr = true
stdout_logfile = /home/zankbo/log/zankbo.log
建立對(duì)應(yīng)的使用者
useradd zankbo
# 將使用者加入到zankbo使用者組,Nginx以使用者執(zhí)行
usermod -a -G zankbo
# 更改使用者家目錄使用者組的許可權(quán),使Nginx可以訪問(wèn)
chmod g+rx /home/zankbo
部署Go環(huán)境
其中的目錄為,go:Go安裝目錄 gopath:Go工作目錄,下面有src、pkg、bin三個(gè)目錄 log:日志資料夾
[zankbo@MyCloudServer ~]$ pwd
/home/zankbo
[zankbo@MyCloudServer ~]$ vim .bashrc
# 設(shè)定Go環(huán)境變數(shù),在.bashrc檔案末尾寫(xiě)下如下內(nèi)容
export GOROOT=$HOME/go
export GOPATH=$HOME/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bi
# 切換到使用者家目錄
[root@MyCloudServer ~]# su - zankbo
[zankbo@MyCloudServer ~]$ ls
go gopath log
將專案程式碼放到gopath/src下面,如我的播客專案:
[zankbo@MyCloudServer ~]$ tree -L 2 gopath/src/
gopath/src/
├── github.
│ ├── astaxie
│ ├── beego
│ ├── go-sql-driver
│ ├── howeyc
│ ├── jacobsa
│ ├── *** artystreets
│ └── wendal
└── zankbo
├── admin
├── blog
├── build_pkg.sh
├── mon
├── conf
├── controllers
├── dbstruct.mwb
├── main.go
├── models
├── static
├── views
└── zankbo
匯入專案sql檔案到資料庫(kù)
在專案資料夾執(zhí)行build
[zankbo@MyCloudServer zankbo]$ pwd
/home/zankbo/gopath/src/zankbo
[zankbo@MyCloudServer zankbo]$ go build
會(huì)在專案下生成與包名對(duì)應(yīng)的可執(zhí)行檔案,這里為:zankbo,build的時(shí)候可能會(huì)遇到錯(cuò)誤,比如mysql的密碼之類的,可根據(jù)提示排錯(cuò)。
通過(guò)supervisor 來(lái)啟動(dòng)服務(wù)
# supervisorctl start zankbo
配置Nginx
server {
listen 80;
server_name zankbo. zankbo.;
root /home/zankbo/gopath/src/zankbo;
error_log logs/zankbo..error.log warn ;
location /static/ {
root /home/zankbo/gopath/src/zankbo;
location ~ .*\.(js|css)$ {
aess_log off;
expires 1d;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
gzip off;
aess_log off;
expires 3d;
}
}
location / {
proxy_pass :127.0.0.1:8080;
}
}
如何部署thinkphp 應(yīng)用
1、首先在官方網(wǎng)站下載ThinkPHP最新版本。
2、下載后的壓縮檔案解壓到WEB目錄(或者任何目錄都可以),框架的目錄結(jié)構(gòu)為:
├─ThinkPHP.php 框架入口檔案
├─Common 框架公共檔案
├─Conf 框架配置檔案
├─Extend 框架擴(kuò)充套件目錄
├─Lang 核心語(yǔ)言包目錄
├─Lib 核心類庫(kù)目錄
│ ├─Behavior 核心行為類庫(kù)
│ ├─Core 核心基類庫(kù)
│ ├─Driver 內(nèi)建驅(qū)動(dòng)
│ │ ├─Cache 內(nèi)建快取驅(qū)動(dòng)
│ │ ├─Db 內(nèi)建資料庫(kù)驅(qū)動(dòng)
│ │ ├─TagLib 內(nèi)建標(biāo)簽驅(qū)動(dòng)
│ │ └─Template 內(nèi)建模板引擎驅(qū)動(dòng)
│ └─Template 內(nèi)建模板引擎
└─Tpl 系統(tǒng)模板目錄
注意,框架的公共入口檔案ThinkPHP.php是不能直接執(zhí)行的,該檔案只能在專案入口檔案中呼叫才能正常執(zhí)行,這是很多新手很容易犯的一個(gè)錯(cuò)誤。
3、接下來(lái)先在WEB根目錄下面建立一個(gè)app子目錄(這個(gè)就是app就是專案名),然后在該目錄下面建立一個(gè)index.php檔案,新增一行簡(jiǎn)單的程式碼:
require '/ThinkPHP框架所在目錄/ThinkPHP.php';
這行程式碼的作用就是載入ThinkPHP框架的入口檔案ThinkPHP.php,這是所有基于ThinkPHP開(kāi)發(fā)應(yīng)用的第一步。然后,在瀏覽器中訪問(wèn)這個(gè)入口檔案。
如何部署應(yīng)用到was上
websphere的預(yù)設(shè)使用記憶體應(yīng)該是256的 你的38的war包部署 不應(yīng)該出現(xiàn)記憶體崩掉的問(wèn)題呀。
部署系統(tǒng)也很簡(jiǎn)單么,就是打成war包,記得打war包得時(shí)候要檢查web.xml的格式 websphere很在意這個(gè)東東的。
然后一步一步的部署就可以了。was慢 但是不會(huì)你那么慢得。可以貼error出來(lái)看看
如何部署python3 的應(yīng)用
mod_python,這是apache內(nèi)建的模組,很嚴(yán)重的依賴于mod_python編譯使用的python版本,和apache配套使用,不推薦
cgi,這個(gè)太old,不推薦,而且nginx不支援cgi方式,只能用ligd或者apache
fastcgi ,這個(gè)是目前流行最廣的做法,通過(guò)flup模組來(lái)支援的,在nginx里對(duì)應(yīng)的配置指令是 fastcgi_pass
spawn-fcgi,這個(gè)是fastcgi多程序管理程式,ligd安裝包附帶的,和
flup效果一樣,區(qū)別是flup是
python程式碼級(jí)引入,spawn-fcgi是外部程式。spawn-fcgi用途很廣,可以支援任意語(yǔ)言開(kāi)發(fā)的代
碼,php,python,perl,只要你程式碼實(shí)現(xiàn)了fastcgi介面,它都可以幫你管理你的程序
scgi,全名是Simple Common Gateway Interface,也是cgi的替代版本,scgi協(xié)議很簡(jiǎn)單,我覺(jué)得和fastcgi差不多,只是沒(méi)有怎么推廣開(kāi)來(lái),nginx對(duì)應(yīng)的配置指令是scgi_pass,你想用就用,flup也支援。
,nginx使用proxy_pass轉(zhuǎn)發(fā),這個(gè)要求后端appplication必須內(nèi)建一個(gè)能處理高并發(fā)的 server,在python的web框架當(dāng)中,只能選擇tornado.
python程式設(shè)計(jì)師喜歡發(fā)明輪子,tornado除了是一個(gè)web framework之外,它還可以單獨(dú)提供高效能
server,所以,如果你采用其他python框架寫(xiě)程式碼,比如說(shuō)bottle,也一樣可以通過(guò)import
tornado 來(lái)啟動(dòng)一個(gè)高效能的
server,同樣的可以采用協(xié)議和nginx一起來(lái)部署。擴(kuò)充套件開(kāi)來(lái),python包里面能處理高并發(fā)的
server還有很多,比如說(shuō)gevent,也可以被其他框架引用來(lái)支援方式部署。
現(xiàn)實(shí)當(dāng)中,用java來(lái)做web程式,通常就用和nginx配合,應(yīng)用伺服器選擇tomcat或者jetty
uwsgi,包括4部分組成,
nginx從0.8.4開(kāi)始內(nèi)建支援uwsgi協(xié)議,uwsgi協(xié)議非常簡(jiǎn)單,一個(gè)4個(gè)位元組header+一個(gè)body,body可以是很多協(xié)議的
包,比如說(shuō),cgi等(通過(guò)header里面欄位標(biāo)示),我曾經(jīng)做個(gè)一個(gè)小規(guī)模的效能對(duì)比測(cè)試,結(jié)果表明,uwsgi和fastcgi相比,效能
沒(méi)有太明顯的優(yōu)勢(shì),也可能是資料集較小的原因
uwsgi的特點(diǎn)在于自帶的程序控制程式.它是用c語(yǔ)言編寫(xiě),使用natvie函式,其實(shí)和spawn-fcgi/php-fpm類似。所以u(píng)wsgi可以支援多種應(yīng)用框架,包括(python,lua,ruby,erlang,go)等等
uwsgi協(xié)議
web server內(nèi)建支援協(xié)議模組
application伺服器協(xié)議支援模組
程序控制程式
Gunicorn,和uwsgi類似的工具,從rails的部署工具(Unicorn)移植過(guò)來(lái)的。但是它使用的協(xié)議是 WSGI,全稱是Python Web Server Gateway Interface ,這是python2.5時(shí)定義的官方標(biāo)準(zhǔn)(PEP 333 ),根紅苗正,而且部署比較簡(jiǎn)單,:gunicorn./ 上有詳細(xì)教程
mod_wsgi,apache的一個(gè)module,也是支援WSGI協(xié)議,:code.google./p/modwsgi/
如何部署簡(jiǎn)單python + flask應(yīng)用
python是一款應(yīng)用非常廣泛的指令碼程式語(yǔ)言,谷歌公司的網(wǎng)頁(yè)就是用python編寫(xiě)。python在生物資訊、統(tǒng)計(jì)、網(wǎng)頁(yè)制作、計(jì)算等多個(gè)領(lǐng)域都體現(xiàn)出了強(qiáng)大的功能。python和其他指令碼語(yǔ)言如java、R、Perl 一樣,都可以直接在命令列里執(zhí)行指令碼程式。
所需工具:
python3.4
flask
nginx
gunicorn
supervisor
系統(tǒng)環(huán)境:
Ubuntu 14.04LTS
我們先寫(xiě)一個(gè)最基本的flask應(yīng)用:
demo.py
from flask import Flask
app = Flask(**name**)
@app.route('\')
def index():
return 'Hello World.'
if __name__ == __main__:
app.run()
執(zhí)行這個(gè)py檔案,開(kāi)啟瀏覽器訪問(wèn)127.0.0.1:5000就能看到顯示Hello World的頁(yè)面 .
如果讓這個(gè)flask引用監(jiān)聽(tīng)來(lái)自公網(wǎng)ip的請(qǐng)求,理論上你跑此程式的機(jī)器就相當(dāng)于一個(gè)伺服器了,然而這個(gè)伺服器并不完美,所以我們需要nginx和gunicorn來(lái)增加它的功能,讓它真刀真槍上生產(chǎn)環(huán)境的時(shí)候能按要求執(zhí)行。
flask自帶的WSGI框架效能很差勁,只能適用于開(kāi)發(fā)環(huán)境除錯(cuò)使用。我們用專業(yè)一點(diǎn)的gunicorn(還有很多其他優(yōu)秀的框架)替代flask自帶的WSGI框架。
配置完后,通過(guò)命令’/usr/local/bin/gunicorn -b127.0.0.1:5000‘啟動(dòng)應(yīng)用。開(kāi)啟瀏覽器訪問(wèn)127.0.0.1:5000,同樣能夠得到返回頁(yè)面
然而gunicorn也僅僅是一個(gè)python的WSGI框架而已,要讓它真正處理來(lái)自網(wǎng)際網(wǎng)路的各類訪問(wèn)功能還是有點(diǎn)欠缺,這時(shí)候就需要用到大名鼎鼎的nginx 伺服器來(lái)替gunicorn遮風(fēng)擋雨了。
Ubuntu下安裝nginx可以用命令
sudo apt-get install nginx
安裝后需要進(jìn)行下配置:
cd /etc/nginx/sites-available
sudo vi test (test為配置名稱,可以根據(jù)自己專案進(jìn)行命名)
test檔案的配置為:
server {
listen 80; # 監(jiān)聽(tīng)80埠
location / {
proxy_pass :127.0.0.1:5000; # 代理本機(jī)127.0.0.1:5000的服務(wù)
}
location /static {
alias /home/ubuntu/myproject/myblog/app/static; # 負(fù)載均衡
}
}
cd ..
cd sites-enable
sudo ln -s ../sites-available/lwhile . (建立軟連結(jié),別漏掉最后的.)
sudo service nginx reload
sudo service nginx restart
這樣nginx的基本配置檔案就寫(xiě)好了 接下來(lái)我們配置程序管理工具supervisor supervisor可以在后面啟動(dòng)你的python程序,這樣很方便
1.cd /etc/supervisor/conf.d
2.sudo vi test.conf (test為檔名)
[program:test]
mand = /usr/local/bin/gunicorn -b127.0.0.1:5000 /home/ubuntu/myproject/test.py
3.sudo supervisorctl
4.reload
5.start test
如果一切正常,做完這所有步驟之后,現(xiàn)在公網(wǎng)的ip訪問(wèn)你的主機(jī),就可以開(kāi)啟你的flask應(yīng)用了
python是一款應(yīng)用非常廣泛的指令碼程式語(yǔ)言,谷歌公司的網(wǎng)頁(yè)就是用python編寫(xiě)。python在生物資訊、統(tǒng)計(jì)、網(wǎng)頁(yè)制作、計(jì)算等多個(gè)領(lǐng)域都體現(xiàn)出了強(qiáng)大的功能。python和其他指令碼語(yǔ)言如java、R、Perl 一樣,都可以直接在命令列里執(zhí)行指令碼程式。工具/原料
python;CMD命令列;windows作業(yè)系統(tǒng)
方法/步驟
1、首先下載安裝python,建議安裝2.7版本以上,3.0版本以下,由于3.0版本以上不向下相容,體驗(yàn)較差。
2、開(kāi)啟文字編輯器,推薦editplus,notepad等,將檔案儲(chǔ)存成 .py格式,editplus和notepad支援識(shí)別python語(yǔ)法。
指令碼第一行一定要寫(xiě)上 #!usr/bin/python
表示該指令碼檔案是可執(zhí)行python指令碼
如果python目錄不在usr/bin目錄下,則替換成當(dāng)前python執(zhí)行程式的目錄。
3、編寫(xiě)完指令碼之后注意除錯(cuò)、可以直接用editplus除錯(cuò)。除錯(cuò)方法可自行百度。指令碼寫(xiě)完之后,開(kāi)啟CMD命令列,前提是python 已經(jīng)被加入到環(huán)境變數(shù)中,如果沒(méi)有加入到環(huán)境變數(shù),請(qǐng)百度
4、在CMD命令列中,輸入 “python” + “空格”,即 ”python “;將已經(jīng)寫(xiě)好的指令碼檔案拖拽到當(dāng)前游標(biāo)位置,然后敲回車執(zhí)行即可。
在以前,你選擇Pythonweb架構(gòu)會(huì)受制于可用的web服務(wù)器,反之亦然。如果架構(gòu)和服務(wù)器可以協(xié)同工作,那你就走運(yùn)了:
但你有可能面對(duì)(或者曾有過(guò))下面的問(wèn)題,當(dāng)要把一個(gè)服務(wù)器和一個(gè)架構(gòu)結(jié)合起來(lái)是發(fā)現(xiàn)他們不是被設(shè)計(jì)成協(xié)同工作的:
基本上你只能用可以一起運(yùn)行的而非你想要使用的。
那么,你怎么可以不修改服務(wù)器和架構(gòu)代碼而確保可以在多個(gè)架構(gòu)下運(yùn)行web服務(wù)器呢?答案就是PythonWebServerGatewayInterface(或簡(jiǎn)稱WSGI,讀作“wizgy”)。
WSGI允許開(kāi)發(fā)者將選擇web框架和web服務(wù)器分開(kāi)。現(xiàn)在你可以混合匹配web服務(wù)器和web框架,選擇一個(gè)適合你需要的配對(duì)。比如,你可以在Gunicorn或者Nginx/uWSGI或者Waitress上運(yùn)行Django,Flask,或Pyramid。真正的混合匹配,得益于WSGI同時(shí)支持服務(wù)器和架構(gòu):
WSGI是第一篇和這篇開(kāi)頭又重復(fù)問(wèn)道問(wèn)題的答案。你的web服務(wù)器必須具備WSGI接口,所有的現(xiàn)代PythonWeb框架都已具備WSGI接口,它讓你不對(duì)代碼作修改就能使服務(wù)器和特點(diǎn)的web框架協(xié)同工作。
現(xiàn)在你知道WSGI由web服務(wù)器支持,而web框架允許你選擇適合自己的配對(duì),但它同樣對(duì)于服務(wù)器和框架開(kāi)發(fā)者提供便利使他們可以專注于自己偏愛(ài)的領(lǐng)域和專長(zhǎng)而不至于相互牽制。其他語(yǔ)言也有類似接口:java有ServletAPI,Ruby有Rack。
說(shuō)這么多了,你肯定在喊,給我看代碼!好吧,看看這個(gè)極簡(jiǎn)的WSGI服務(wù)器實(shí)現(xiàn):
#TestedwithPython2.7.9,LinuxMacOSX
importsocket
importStringIO
importsys
classWSGIServer(object):
address_family=socket.AF_INET
socket_type=socket.SOCK_STREAM
request_queue_size=1
def__init__(self,server_address):
#Createalisteningsocket
self.listen_socket=listen_socket=socket.socket(
self.address_family,
self.socket_type
)
#Allowtoreusethesameaddress
listen_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#Bind
listen_socket.bind(server_address)
#Activate
listen_socket.listen(self.request_queue_size)
#Getserverhostnameandport
host,port=self.listen_socket.getsockname()[:2]
self.server_name=socket.getfqdn(host)
self.server_port=port
#ReturnheaderssetbyWebframework/Webapplication
self.headers_set=[]
defset_app(self,application):
self.application=application
defserve_forever(self):
listen_socket=self.listen_socket
whileTrue:
#Newclientconnection
self.client_connection,client_address=listen_socket.accept()
#Handleonerequestandclosetheclientconnection.Then
#loopovertowaitforanotherclientconnection
self.handle_one_request()
defhandle_one_request(self):
self.request_data=request_data=self.client_connection.recv(1024)
#Printformattedrequestdataala'curl-v'
print(''.join(
'{line}\n'.format(line=line)
forlineinrequest_data.splitlines()
))
self.parse_request(request_data)
#Constructenvironmentdictionaryusingrequestdata
env=self.get_environ()
#It'stimetocallourapplicationcallableandget
#backaresultthatwillbecomeHTTPresponsebody
result=self.application(env,self.start_response)
#Constructaresponseandsenditbacktotheclient
self.finish_response(result)
defparse_request(self,text):
request_line=text.splitlines()[0]
request_line=request_line.rstrip('\r\n')
#Breakdowntherequestlineintocomponents
(self.request_method,#GET
self.path,#/hello
self.request_version#HTTP/1.1
)=request_line.split()
defget_environ(self):
env={}
#ThefollowingcodesnippetdoesnotfollowPEP8conventions
#butit'sformattedthewayitisfordemonstrationpurposes
#toemphasizetherequiredvariablesandtheirvalues
#
#RequiredWSGIvariables
env['wsgi.version']=(1,0)
env['wsgi.url_scheme']='http'
env['wsgi.input']=StringIO.StringIO(self.request_data)
env['wsgi.errors']=sys.stderr
env['wsgi.multithread']=False
env['wsgi.multiprocess']=False
env['wsgi.run_once']=False
#RequiredCGIvariables
env['REQUEST_METHOD']=self.request_method#GET
env['PATH_INFO']=self.path#/hello
env['SERVER_NAME']=self.server_name#localhost
env['SERVER_PORT']=str(self.server_port)#8888
returnenv
defstart_response(self,status,response_headers,exc_info=None):
#Addnecessaryserverheaders
server_headers=[
('Date','Tue,31Mar201512:54:48GMT'),
('Server','WSGIServer0.2'),
]
self.headers_set=[status,response_headers+server_headers]
#ToadheretoWSGIspecificationthestart_responsemustreturn
#a'write'callable.Wesimplicity'ssakewe'llignorethatdetail
#fornow.
#returnself.finish_response
deffinish_response(self,result):
try:
status,response_headers=self.headers_set
response='HTTP/1.1{status}\r\n'.format(status=status)
forheaderinresponse_headers:
response+='{0}:{1}\r\n'.format(*header)
response+='\r\n'
fordatainresult:
response+=data
#Printformattedresponsedataala'curl-v'
print(''.join(
'{line}\n'.format(line=line)
forlineinresponse.splitlines()
))
self.client_connection.sendall(response)
finally:
self.client_connection.close()
SERVER_ADDRESS=(HOST,PORT)='',8888
defmake_server(server_address,application):
server=WSGIServer(server_address)
server.set_app(application)
returnserver
if__name__=='__main__':
iflen(sys.argv)2:
sys.exit('ProvideaWSGIapplicationobjectasmodule:callable')
app_path=sys.argv[1]
module,application=app_path.split(':')
module=__import__(module)
application=getattr(module,application)
httpd=make_server(SERVER_ADDRESS,application)
print('WSGIServer:ServingHTTPonport{port}...\n'.format(port=PORT))
httpd.serve_forever()
這比第一篇的代碼長(zhǎng)的多,但也足夠短(只有150行)來(lái)讓你理解而避免在細(xì)節(jié)里越陷越深。上面的服務(wù)器可以做更多——可以運(yùn)行你鐘愛(ài)web框架所寫(xiě)基本的web應(yīng)用,Pyramid,Flask,Django,或其他PythonWSGI框架.
不相信我?你自己試試看。保存上面的代碼為webserver2.py或者直接在Github下載。如果你不傳入任何參數(shù)它會(huì)提醒然后推出。
$pythonwebserver2.py
ProvideaWSGIapplicationobjectasmodule:callable
名稱欄目:wsgi支持go語(yǔ)言 go語(yǔ)言做web有優(yōu)勢(shì)嗎?
文章鏈接:http://chinadenli.net/article22/doedijc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、全網(wǎng)營(yíng)銷推廣、做網(wǎng)站、企業(yè)建站、、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)