1. 程式人生 > >【Python】 Web開發框架的基本概念與開發的準備工作

【Python】 Web開發框架的基本概念與開發的準備工作

世紀 依賴包 ade 並不是 模板 界面 inux tar cal

Web框架基本概念

現在再來寫這篇文章顯然有些馬後炮的意思。不過正是因為已經學習了Flask框架, 並且未來計劃學習更加體系化的Django框架,在學習過程中碰到的很多術語等等,非常有必要通過這樣一篇看似都是空話但堅實地理論知識學習來填充自己

■  MVC體系的框架

Python發展到今天,已經有了數十種不同的Web框架。其中比較著名,被廣泛的使用的有Django,Flask,Tornado,Twisted等等。作為Web框架,它們都向使用者提供了對於網絡和線程的封裝,借此可以實現HTTP請求-應答模型的定制。另外前三種還提供了關於HTML模板,數據庫讀寫管理,HTTP棧等從前臺到後端的一系列方便的封裝。有這些封裝的框架又被稱為全棧框架,是開發人員的好助手。


  MVC即Model,View和Controller。是在上世紀八十年代左右發展出來的一種軟件架構模式。其中Model,模型封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法,是Web程序中用於處理應用程序的數據邏輯部分,Model只提供性能性的接口,通過這些接口可以調用Model來訪問數據。有些模型還提供了事件通知機制,為在其上註冊的View和Controller提供數據的實時更新。

  View是視圖,負責數據的顯示和呈現,View是對用戶的直接輸出,在MVC中,一個model往往要給多個View提供服務,View需要盡早註冊到Model中去

  Controller是控制器,負責從用戶端收集數據,可以看做是View的一個反向操作。也就是說Controller的作用是根據用戶的旨意來改變View。當然這種改變可能不直接在兩者之間進行,而是通過Model作為一個數據中心來聯系兩者。

  因為MVC三者之間互相隔離,所以在程序的發展過程中,改進界面、用戶交互流程等要素時不用重寫整個程序的邏輯,只要替換其中相關的一部分即可。

■  Python虛擬環境的安裝

  很早以前,第一次學習python的時候就看到過virturalenv這個東西。當時沒有重視虛擬環境這種設定,但是在做Web開發的時候最好還是用虛擬環境。因為在一臺電腦上進行多個web項目的開發的時候,不同的項目可能對支持包的要求不同,版本也有可能不同。如果都用默認的python環境,A項目要求某個包版本是1.0,B項目要求是2.0時就沖突了。如果有了虛擬環境,我們可以為一個項目單獨起一個虛擬環境來管理它需要的依賴包。

  建立虛擬環境用的包叫virtualenv,可以通過pip install virtualenv 來安裝。安裝完成之後,在某個特定的目錄下鍵入命令

virtualenv venv

  即可在目錄下生成一個名為venv的目錄,目錄中存放的是Python虛擬環境,主要包括Include,Lib,Scripts等幾個目錄,這些目錄的功能和PythonHome中的同名目錄是類似的。利用虛擬環境中的venv/Scripts/python.exe作為二進制文件來執行相關的腳本的話這個腳本的環境就是當前venv這個虛擬環境了。

  如果覺得還要寫路徑很麻煩的話,那麽可以運行venv/Scripts/activate.exe以把當前系統的Python上下文切換到虛擬環境中,此時直接運行python指向的就是虛擬環境的python了。如果想要退出虛擬環境的上下文,可以運行venv/Scripts/deactivate.exe來退出。

■  Web服務器

  雖然口頭上我們常說,用web框架開發出一個服務器,但是需要明確知道的是,Web框架開發出來的只是服務端程序,而真正的Web服務器並不是我們開發的。Web服務器是連接用戶瀏覽器和Python服務器端程序的中間節點,目前主流的Web服務器可以選擇Nginx,Apache,lighthttpd,IIS等。這些服務器組件,其作用就是在服務器端開啟一個httpd進程(當然不止是一個,也不一定叫httpd,總之是這麽個意思)來接受外界的請求。

  另外,要實現Web服務器和python程序之間的連接,還需要一層叫做WSGI的程序。WSGI的代表有uWSGI,Apache,mod_wsgi等。WSGI全稱是Web Server Gateway Interface,其本質是一個接口層,一邊聯系了Web服務器,另一邊聯系了Pythonweb程序。與Web服務器連接的一端的接口的例子有uwsgi,fast cgi等,這些東西都是WSGI程序本身實現的,我們需要關註的是如何按照WSGI規定來對接我們自己的程序和WSGI之間的接口。

  利用python自帶的一些wsgi的實現包可以進行簡單的WSGI到服務程序的接口設計。比如:

def application(env, start_reponse):
    start_response(200 OK,[(Content-Type,text/html)])
    return <h1>Hello,World</h1>
####這個application函數就可以視作是一個簡單的服務端程序####


####下面就是在編寫wsgi到服務端程序的接口了####
from wsgiref.simple_server import make_server

if __name__ == __main__:
    server = make_server(‘‘,8080,application)
    server.serve_forever()

  在這個程序開始運行之後,訪問localhost:8080就可以看到固定的h1的Hello,World了。從中也可以看到,雖然之前說WSGI程序是作為接口層連接服務程序和Web服務器的,但是WSGI本身也可以作為Web服務器來運行。這個例子中我們沒有設置任何一個類似於Nginx的服務器,但是也能讓它運行了。不過因為性能方面的原因,沒有生產環境的程序會直接拿WSGI程序來做服務器,所以WSGI作為Web服務器來監聽外界請求大多只用在測試環境。

  事實上,上面這個程序包裝的WSGI接口層也不是很方便進行服務程序的開發,所以Web開發框架基本上都會把這層接口的開發封裝完畢,我們只需要使用uWSGI等WSGI程序的實例和它進行一下對接,也不用怎麽關心實現。這樣一來我們就可以只關註服務程序的開發了。

■  用Linux+Nginx+uWSGI作為依托發布Web應用

  之前在學習Flask的時候有專門寫過一篇關於這個的文章:【http://www.cnblogs.com/franknihao/p/7202253.html】,這裏對這個文章進行一定程度的補充。

  ● 安裝配置nginx

  首先是通過默認yum(Redhat系列)或者apt-get(Ubuntu系列)獲得的nginx,主要安裝到了以下位置

  /usr/sbin/nginx  二進制可執行文件的地方

  /etc/nginx/nginx.conf  全局配置文件

  /var/log/nginx/access.log  訪問日誌

  /var/log/nginx/error.log  錯誤日誌

  之前那篇文章對於/etc/nginx/conf.d中的配置文件有過簡單描述,但是對於全局配置文件/etc/nginx/nginx.conf一帶而過了。現在先來看看這個nginx.conf的一些配置。:

user nginx;    ##定義運行Nginx的用戶

worker_process 4;    ##Nginx的最大進程數,應該設置成和系統CPU個數相同比較合理

pid /var/run/nginx.pid;

worker_rlimit_nofile 65535;    ##限制每個nginx進程最多可以打開多少文件

events{
    worker_connections 768;    ##每個Nginx進程允許連接的最大客戶端數目
}

http{
    #########
    #一些基本設置
    #########
    sendfile on;    #是否允許文件上傳
    clilent_header_buffer_size 32k;    #上傳文件大小限制

    tcp_nopush on;    #防止網絡阻塞
    tcp_nodelay on;    #防止網絡阻塞
    keepalive_timeout 65;    #允許客戶端長連接的最大秒數

    types_hash_max_size 2048;    #Nginx散列表大小設置,這個值設置得越大,占用的內存空間就越大,但是路由速度也會越快

    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    include /etc/nginx/conf.d/*.conf;    #加載站點配置文件
    include /etc/nginx/site-enabled/*;    #加載站點配置文件
}

  上面最後兩行提到的站點配置文件的話,nginx開啟服務之後可以在它身後配置很多個服務程序,每個服務程序都可以視作一個Web站點。把所有站點都配置在nginx.conf中顯然不合理,所以在conf.d中寫各種不同的站點的配置,然後再把它們include進來這樣的做法更加合適。每個站點的conf文件都是配置了一個server代碼塊,比如下面這個例子:

server{
    listen 80;    ##指出監聽的端口,一般而言一個站點監聽一個端口。是事實上不同的server代碼塊中不允許有相同的listen端口出現,
否則會強行忽略其中的某一些站點。所以如果為了訪問的友好性,輸入url時不打入端口號(默認80端口)的話,
可能需要全局只能配置一個server代碼塊,然後不同站點的訪問通過後續的路由設置來實現。
root /usr/share/nginx/html; ##配置HTTP根頁面目錄,nginx提供了一些默認的html文件用於訪問一些基礎頁面時的默認顯示。 index index.html index.htm ##配置HTTP根頁面中的默認頁面 server_name localhost; location /users/ { ##此處配置的是http://server_name/users/的轉發地址 proxy_pass http://127.0.0.1:8080/; ##把指向users的所有路由都轉發到本機的8080端口的/界面 proxy_redirect default; } error_page 404 /404.html ##配置錯誤頁面指向的模板 }

  配置完成之後,可以nginx -t來測試配置文件是否在語法上沒有問題,如果OK,就可以鍵入nginx啟動nginx,nginx -s stop關閉,nginx -s reload重新加載配置文件啟動。

  *nginx的配置文件,裏面的技巧和細節還是很多的,這裏只是粗粗過了一下,以後如果有需要可能得專門學習一下怎麽配置nginx。

  ● 安裝配置uWSGI

  uWSGI是在linux上一種對於WSGI程序的實現。可以直接通過pip install uwsgi(註意,是小寫的哦)安裝。啟動方法可以是uwsgi --http:8080 --wsgi-file app.py。這個啟動的意思就是說開啟8080端口接受http請求,並且後端的服務程序由app.py提供。

  除了這種命令行的啟動方式,實際上用得更多的是一種基於ini配置文件來進行啟動的辦法。即鍵入命令uwsgi uwsgi.ini。關於配置文件uwsgi.ini的寫法,在那篇發布flask的文章裏詳細提到過,這裏再簡單說明一下:

[uwsgi]
#http = 9090
socket = 127.0.0.1:9090
chdir = /opt/Flasky
uid = 500 wsgi-file = webapp.py processes = 4 threads = 3

  processes和threads就是指定了uwsgi程序開啟的進程數和每個進程最大處理的線程數。也就是說,總的處理線程最大數目是processs * threads。chdir指定了uwsgi開啟之後的當前目錄,這樣可以讓wsgi-file等涉及路徑的內容寫相對路徑即可。uid指定了運行uwsgi程序的用戶是誰。

  http指定直接通過http方法訪問uwsgi程序時的端口號。socket指定了通過socket的方式來和uwsgi進行對接的地址,一般而言,這個socket接口就是和類似於Nginx等Web服務器進行對接的地址。如果確定是進行Nginx+uWSGI的方式部署web應用的話,那麽可以不用寫http,而寫socket。

  當uwsgi的配置文件裏寫下了socket的話,在nginx的配置文件裏進行指向該socket的配置就可以讓前端請求信息通達到後端的服務程序了。比如按照上面的uwsgi.ini中設置的socket,在nginx中設置:

server {
  listen 80;

  location / {
    uwsgi_pass http://127.0.0.1:9090;
  }

}

  ● 建立https網站

  基於SSL協議進行傳輸的HTTP數據就是HTTPS的範疇了。下面簡單介紹一下如何建立一個HTTPS站點。

  針對每一個想要訪問HTTPS站點的客戶端,都需要經過這樣的一些步驟:

  1.在服務器中安裝OpenSSL等相關的依賴包

  2. 生成SSL秘鑰和證書

  3. 將證書配置到Web服務器

  4. 在客戶端安裝CA證書

  首先可以通過yum或者apt-get來安裝openssl和openssl-devel兩個包。安裝完成之後,默認配置下,可執行文件/usr/bin/openssl 以及 相關配置文件 /usr/lib/ssl/* 會被安裝到系統中。然後依次執行以下命令來生成CA證書,服務器秘鑰以及服務器證書:

#生成CA密鑰
openssl genrsa -out ca.key 2048

#生成CA證書,days參數以天數為單位設置證書的有效期,在本過程中會要求輸入證書的所在地,公司名,站點名等等
openssl req -x509 -new -nodes -key ca.key -days 365 -out ca.crt

#生成服務器證書的RSA密鑰對
openssl genrsa -out server.key 2048

#生成服務器端證書CSR,要求輸入證書的所在地,公司名,站點名
openssl req -new -key server.key -out server.csr

#生成服務器端證書ca.crt
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365

  把一些必要的東西都生成好之後,就可以再調整一下nginx的配置,使HTTPS站點生效了

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必須使用指向服務器證書和服務器密鑰的絕對路徑。

【Python】 Web開發框架的基本概念與開發的準備工作