【Python】 Web开发框架的基本概念与开发的准备工作
Web框架基本概念
? 現(xiàn)在再來寫這篇文章顯然有些馬后炮的意思。不過正是因?yàn)橐呀?jīng)學(xué)習(xí)了Flask框架, 并且未來計(jì)劃學(xué)習(xí)更加體系化的Django框架,在學(xué)習(xí)過程中碰到的很多術(shù)語等等,非常有必要通過這樣一篇看似都是空話但堅(jiān)實(shí)地理論知識(shí)學(xué)習(xí)來填充自己
■ MVC體系的框架
Python發(fā)展到今天,已經(jīng)有了數(shù)十種不同的Web框架。其中比較著名,被廣泛的使用的有Django,Flask,Tornado,Twisted等等。作為Web框架,它們都向使用者提供了對(duì)于網(wǎng)絡(luò)和線程的封裝,借此可以實(shí)現(xiàn)HTTP請(qǐng)求-應(yīng)答模型的定制。另外前三種還提供了關(guān)于HTML模板,數(shù)據(jù)庫讀寫管理,HTTP棧等從前臺(tái)到后端的一系列方便的封裝。有這些封裝的框架又被稱為全??蚣?#xff0c;是開發(fā)人員的好助手。
MVC即Model,View和Controller。是在上世紀(jì)八十年代左右發(fā)展出來的一種軟件架構(gòu)模式。其中Model,模型封裝與應(yīng)用程序的業(yè)務(wù)邏輯相關(guān)的數(shù)據(jù)以及對(duì)數(shù)據(jù)的處理方法,是Web程序中用于處理應(yīng)用程序的數(shù)據(jù)邏輯部分,Model只提供性能性的接口,通過這些接口可以調(diào)用Model來訪問數(shù)據(jù)。有些模型還提供了事件通知機(jī)制,為在其上注冊(cè)的View和Controller提供數(shù)據(jù)的實(shí)時(shí)更新。
View是視圖,負(fù)責(zé)數(shù)據(jù)的顯示和呈現(xiàn),View是對(duì)用戶的直接輸出,在MVC中,一個(gè)model往往要給多個(gè)View提供服務(wù),View需要盡早注冊(cè)到Model中去
Controller是控制器,負(fù)責(zé)從用戶端收集數(shù)據(jù),可以看做是View的一個(gè)反向操作。也就是說Controller的作用是根據(jù)用戶的旨意來改變View。當(dāng)然這種改變可能不直接在兩者之間進(jìn)行,而是通過Model作為一個(gè)數(shù)據(jù)中心來聯(lián)系兩者。
因?yàn)镸VC三者之間互相隔離,所以在程序的發(fā)展過程中,改進(jìn)界面、用戶交互流程等要素時(shí)不用重寫整個(gè)程序的邏輯,只要替換其中相關(guān)的一部分即可。
?
■ Python虛擬環(huán)境的安裝
很早以前,第一次學(xué)習(xí)python的時(shí)候就看到過virturalenv這個(gè)東西。當(dāng)時(shí)沒有重視虛擬環(huán)境這種設(shè)定,但是在做Web開發(fā)的時(shí)候最好還是用虛擬環(huán)境。因?yàn)樵谝慌_(tái)電腦上進(jìn)行多個(gè)web項(xiàng)目的開發(fā)的時(shí)候,不同的項(xiàng)目可能對(duì)支持包的要求不同,版本也有可能不同。如果都用默認(rèn)的python環(huán)境,A項(xiàng)目要求某個(gè)包版本是1.0,B項(xiàng)目要求是2.0時(shí)就沖突了。如果有了虛擬環(huán)境,我們可以為一個(gè)項(xiàng)目單獨(dú)起一個(gè)虛擬環(huán)境來管理它需要的依賴包。
建立虛擬環(huán)境用的包叫virtualenv,可以通過pip install virtualenv 來安裝。安裝完成之后,在某個(gè)特定的目錄下鍵入命令
virtualenv venv?
即可在目錄下生成一個(gè)名為venv的目錄,目錄中存放的是Python虛擬環(huán)境,主要包括Include,Lib,Scripts等幾個(gè)目錄,這些目錄的功能和PythonHome中的同名目錄是類似的。利用虛擬環(huán)境中的venv/Scripts/python.exe作為二進(jìn)制文件來執(zhí)行相關(guān)的腳本的話這個(gè)腳本的環(huán)境就是當(dāng)前venv這個(gè)虛擬環(huán)境了。
如果覺得還要寫路徑很麻煩的話,那么可以運(yùn)行venv/Scripts/activate.exe以把當(dāng)前系統(tǒng)的Python上下文切換到虛擬環(huán)境中,此時(shí)直接運(yùn)行python指向的就是虛擬環(huán)境的python了。如果想要退出虛擬環(huán)境的上下文,可以運(yùn)行venv/Scripts/deactivate.exe來退出。(Linux上的話是source bin/activate進(jìn)入環(huán)境。在虛擬環(huán)境中鍵入deactivate退出虛擬環(huán)境。)
?
■ Web服務(wù)器
雖然口頭上我們常說,用web框架開發(fā)出一個(gè)服務(wù)器,但是需要明確知道的是,Web框架開發(fā)出來的只是服務(wù)端程序,而真正的Web服務(wù)器并不是我們開發(fā)的。Web服務(wù)器是連接用戶瀏覽器和Python服務(wù)器端程序的中間節(jié)點(diǎn),目前主流的Web服務(wù)器可以選擇Nginx,Apache,lighthttpd,IIS等。這些服務(wù)器組件,其作用就是在服務(wù)器端開啟一個(gè)httpd進(jìn)程(當(dāng)然不止是一個(gè),也不一定叫httpd,總之是這么個(gè)意思)來接受外界的請(qǐng)求。
另外,要實(shí)現(xiàn)Web服務(wù)器和python程序之間的連接,還需要一層叫做WSGI的程序。WSGI的代表有uWSGI,Apache,mod_wsgi等。WSGI全稱是Web Server Gateway Interface,其本質(zhì)是一個(gè)接口層,一邊聯(lián)系了Web服務(wù)器,另一邊聯(lián)系了Pythonweb程序。與Web服務(wù)器連接的一端的接口的例子有uwsgi,fast cgi等,這些東西都是WSGI程序本身實(shí)現(xiàn)的,我們需要關(guān)注的是如何按照WSGI規(guī)定來對(duì)接我們自己的程序和WSGI之間的接口。
利用python自帶的一些wsgi的實(shí)現(xiàn)包可以進(jìn)行簡單的WSGI到服務(wù)程序的接口設(shè)計(jì)。比如:
def application(env, start_reponse):start_response('200 OK',[('Content-Type','text/html')])return '<h1>Hello,World</h1>' ####這個(gè)application函數(shù)就可以視作是一個(gè)簡單的服務(wù)端程序########下面就是在編寫wsgi到服務(wù)端程序的接口了#### from wsgiref.simple_server import make_serverif __name__ == '__main__':server = make_server('',8080,application)server.serve_forever()?
在這個(gè)程序開始運(yùn)行之后,訪問localhost:8080就可以看到固定的h1的Hello,World了。從中也可以看到,雖然之前說WSGI程序是作為接口層連接服務(wù)程序和Web服務(wù)器的,但是WSGI本身也可以作為Web服務(wù)器來運(yùn)行。這個(gè)例子中我們沒有設(shè)置任何一個(gè)類似于Nginx的服務(wù)器,但是也能讓它運(yùn)行了。不過因?yàn)樾阅芊矫娴脑?#xff0c;沒有生產(chǎn)環(huán)境的程序會(huì)直接拿WSGI程序來做服務(wù)器,所以WSGI作為Web服務(wù)器來監(jiān)聽外界請(qǐng)求大多只用在測(cè)試環(huán)境。
事實(shí)上,上面這個(gè)程序包裝的WSGI接口層也不是很方便進(jìn)行服務(wù)程序的開發(fā),所以Web開發(fā)框架基本上都會(huì)把這層接口的開發(fā)封裝完畢,我們只需要使用uWSGI等WSGI程序的實(shí)例和它進(jìn)行一下對(duì)接,也不用怎么關(guān)心實(shí)現(xiàn)。這樣一來我們就可以只關(guān)注服務(wù)程序的開發(fā)了。
?
■ 用Linux+Nginx+uWSGI作為依托發(fā)布Web應(yīng)用
之前在學(xué)習(xí)Flask的時(shí)候有專門寫過一篇關(guān)于這個(gè)的文章:【http://www.cnblogs.com/franknihao/p/7202253.html】,這里對(duì)這個(gè)文章進(jìn)行一定程度的補(bǔ)充。
●? 安裝配置nginx
首先是通過默認(rèn)yum(Redhat系列)或者apt-get(Ubuntu系列)獲得的nginx,主要安裝到了以下位置
/usr/sbin/nginx 二進(jìn)制可執(zhí)行文件的地方
/etc/nginx/nginx.conf 全局配置文件
/var/log/nginx/access.log 訪問日志
/var/log/nginx/error.log 錯(cuò)誤日志
之前那篇文章對(duì)于/etc/nginx/conf.d中的配置文件有過簡單描述,但是對(duì)于全局配置文件/etc/nginx/nginx.conf一帶而過了?,F(xiàn)在先來看看這個(gè)nginx.conf的一些配置。:
user nginx; ##定義運(yùn)行Nginx的用戶 worker_process 4; ##Nginx的最大進(jìn)程數(shù),應(yīng)該設(shè)置成和系統(tǒng)CPU個(gè)數(shù)相同比較合理 pid /var/run/nginx.pid;worker_rlimit_nofile 65535; ##限制每個(gè)nginx進(jìn)程最多可以打開多少文件 events{worker_connections 768; ##每個(gè)Nginx進(jìn)程允許連接的最大客戶端數(shù)目 }http{##########一些基本設(shè)置#########sendfile on; #是否允許文件上傳clilent_header_buffer_size 32k; #上傳文件大小限制 tcp_nopush on; #防止網(wǎng)絡(luò)阻塞tcp_nodelay on; #防止網(wǎng)絡(luò)阻塞keepalive_timeout 65; #允許客戶端長連接的最大秒數(shù) types_hash_max_size 2048; #Nginx散列表大小設(shè)置,這個(gè)值設(shè)置得越大,占用的內(nèi)存空間就越大,但是路由速度也會(huì)越快 error_log /var/log/nginx/error.log;access_log /var/log/nginx/access.log;include /etc/nginx/conf.d/*.conf; #加載站點(diǎn)配置文件include /etc/nginx/site-enabled/*; #加載站點(diǎn)配置文件 }?
上面最后兩行提到的站點(diǎn)配置文件的話,nginx開啟服務(wù)之后可以在它身后配置很多個(gè)服務(wù)程序,每個(gè)服務(wù)程序都可以視作一個(gè)Web站點(diǎn)。把所有站點(diǎn)都配置在nginx.conf中顯然不合理,所以在conf.d中寫各種不同的站點(diǎn)的配置,然后再把它們include進(jìn)來這樣的做法更加合適。每個(gè)站點(diǎn)的conf文件都是配置了一個(gè)server代碼塊,比如下面這個(gè)例子:
server{listen 80; ##指出監(jiān)聽的端口,一般而言一個(gè)站點(diǎn)監(jiān)聽一個(gè)端口。是事實(shí)上不同的server代碼塊中不允許有相同的listen端口出現(xiàn),否則會(huì)強(qiáng)行忽略其中的某一些站點(diǎn)。所以如果為了訪問的友好性,輸入url時(shí)不打入端口號(hào)(默認(rèn)80端口)的話,
可能需要全局只能配置一個(gè)server代碼塊,然后不同站點(diǎn)的訪問通過后續(xù)的路由設(shè)置來實(shí)現(xiàn)。 root /usr/share/nginx/html; ##配置HTTP根頁面目錄,nginx提供了一些默認(rèn)的html文件用于訪問一些基礎(chǔ)頁面時(shí)的默認(rèn)顯示。index index.html index.htm ##配置HTTP根頁面中的默認(rèn)頁面 server_name localhost;location /users/ {##此處配置的是http://server_name/users/的轉(zhuǎn)發(fā)地址proxy_pass http://127.0.0.1:8080/; ##把指向users的所有路由都轉(zhuǎn)發(fā)到本機(jī)的8080端口的/界面 proxy_redirect default;}error_page 404 /404.html ##配置錯(cuò)誤頁面指向的模板 }
?
配置完成之后,可以nginx -t來測(cè)試配置文件是否在語法上沒有問題,如果OK,就可以鍵入nginx啟動(dòng)nginx,nginx -s stop關(guān)閉,nginx -s reload重新加載配置文件啟動(dòng)。
?
*nginx的配置文件,里面的技巧和細(xì)節(jié)還是很多的,這里只是粗粗過了一下,以后如果有需要可能得專門學(xué)習(xí)一下怎么配置nginx。
? ●? 安裝配置uWSGI
uWSGI是在linux上一種對(duì)于WSGI程序的實(shí)現(xiàn)??梢灾苯油ㄟ^pip install uwsgi(注意,是小寫的哦)安裝。啟動(dòng)方法可以是uwsgi --http:8080 --wsgi-file app.py。這個(gè)啟動(dòng)的意思就是說開啟8080端口接受http請(qǐng)求,并且后端的服務(wù)程序由app.py提供。
除了這種命令行的啟動(dòng)方式,實(shí)際上用得更多的是一種基于ini配置文件來進(jìn)行啟動(dòng)的辦法。即鍵入命令uwsgi uwsgi.ini。關(guān)于配置文件uwsgi.ini的寫法,在那篇發(fā)布flask的文章里詳細(xì)提到過,這里再簡單說明一下:
[uwsgi] #http = 9090 socket = 127.0.0.1:9090chdir = /opt/Flasky
uid = 500 wsgi-file = webapp.py processes = 4 threads = 3
?
processes和threads就是指定了uwsgi程序開啟的進(jìn)程數(shù)和每個(gè)進(jìn)程最大處理的線程數(shù)。也就是說,總的處理線程最大數(shù)目是processs * threads。chdir指定了uwsgi開啟之后的當(dāng)前目錄,這樣可以讓wsgi-file等涉及路徑的內(nèi)容寫相對(duì)路徑即可。uid指定了運(yùn)行uwsgi程序的用戶是誰。
http指定直接通過http方法訪問uwsgi程序時(shí)的端口號(hào)。socket指定了通過socket的方式來和uwsgi進(jìn)行對(duì)接的地址,一般而言,這個(gè)socket接口就是和類似于Nginx等Web服務(wù)器進(jìn)行對(duì)接的地址。如果確定是進(jìn)行Nginx+uWSGI的方式部署web應(yīng)用的話,那么可以不用寫http,而寫socket。
當(dāng)uwsgi的配置文件里寫下了socket的話,在nginx的配置文件里進(jìn)行指向該socket的配置就可以讓前端請(qǐng)求信息通達(dá)到后端的服務(wù)程序了。比如按照上面的uwsgi.ini中設(shè)置的socket,在nginx中設(shè)置:
server {listen 80;location / {uwsgi_pass http://127.0.0.1:9090;}}?
●? 建立https網(wǎng)站
基于SSL協(xié)議進(jìn)行傳輸?shù)腍TTP數(shù)據(jù)就是HTTPS的范疇了。下面簡單介紹一下如何建立一個(gè)HTTPS站點(diǎn)。
針對(duì)每一個(gè)想要訪問HTTPS站點(diǎn)的客戶端,都需要經(jīng)過這樣的一些步驟:
1.在服務(wù)器中安裝OpenSSL等相關(guān)的依賴包
2. 生成SSL秘鑰和證書
3. 將證書配置到Web服務(wù)器
4. 在客戶端安裝CA證書
首先可以通過yum或者apt-get來安裝openssl和openssl-devel兩個(gè)包。安裝完成之后,默認(rèn)配置下,可執(zhí)行文件/usr/bin/openssl 以及 相關(guān)配置文件 /usr/lib/ssl/* 會(huì)被安裝到系統(tǒng)中。然后依次執(zhí)行以下命令來生成CA證書,服務(wù)器秘鑰以及服務(wù)器證書:
#生成CA密鑰 openssl genrsa -out ca.key 2048#生成CA證書,days參數(shù)以天數(shù)為單位設(shè)置證書的有效期,在本過程中會(huì)要求輸入證書的所在地,公司名,站點(diǎn)名等等 openssl req -x509 -new -nodes -key ca.key -days 365 -out ca.crt#生成服務(wù)器證書的RSA密鑰對(duì) openssl genrsa -out server.key 2048#生成服務(wù)器端證書CSR,要求輸入證書的所在地,公司名,站點(diǎn)名 openssl req -new -key server.key -out server.csr#生成服務(wù)器端證書ca.crt openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365?
把一些必要的東西都生成好之后,就可以再調(diào)整一下nginx的配置,使HTTPS站點(diǎn)生效了
server{listen 443;server_name 0.0.0.0;ssl on;ssl_certificate /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;location / {uwsgi_pass http://127.0.0.1:9090;}}?
需要注意的是ssl_certificate和ssl_sertificate_key必須使用指向服務(wù)器證書和服務(wù)器密鑰的絕對(duì)路徑。
總結(jié)
以上是生活随笔為你收集整理的【Python】 Web开发框架的基本概念与开发的准备工作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吴恩达机器学习笔记_第三周
- 下一篇: python 简易HTTP服务器搭建