部署Python的架構下的web app的詳細教程

來源:互聯網
上載者:User
作為一個合格的開發人員,在本地環境下完成開發還遠遠不夠,我們需要把Web App部署到遠程伺服器上,這樣,廣大使用者才能訪問到網站。

很多做開發的同學把部署這件事情看成是營運同學的工作,這種看法是完全錯誤的。首先,最近流行DevOps理念,就是說,開發和營運要變成一個整體。其次,營運的難度,其實跟開發品質有很大的關係。代碼寫得垃圾,營運再好也架不住天天掛掉。最後,DevOps理念需要把營運、監控等功能融入到開發中。你想伺服器升級時不中斷使用者服務?那就得在開發時考慮到這一點。

下面,我們就來把awesome-python-webapp部署到Linux伺服器。
搭建Linux伺服器

要部署到Linux,首先得有一台Linux伺服器。要在公網上體驗的同學,可以在Amazon的AWS申請一台EC2虛擬機器(免費使用1年),或者使用國內的一些雲端服務器,一般都提供Ubuntu Server的鏡像。想在本地部署的同學,請安裝虛擬機器,推薦使用VirtualBox。

我們選擇的Linux伺服器版本是Ubuntu Server 12.04 LTS,原因是apt太簡單了。如果你準備使用其他Linux版本,也沒有問題。

Linux安裝完成後,請確保ssh服務正在運行,否則,需要通過apt安裝:

$ sudo apt-get install openssh-server

有了ssh服務,就可以從本地串連到伺服器上。建議把公開金鑰複製到伺服器端使用者的.ssh/authorized_keys中,這樣,就可以通過認證實現無密碼串連。
部署方式

在本地開發時,我們可以用Python內建的WSGI伺服器,但是,在伺服器上,顯然不能用內建的這個開發版伺服器。可以選擇的WSGI伺服器很多,我們選gunicorn:它用類似Nginx的Master-Worker模式,同時可以提供gevent的支援,不用修改代碼,就能獲得極高的效能。

此外,我們還需要一個高效能Web伺服器,這裡選擇Nginx,它可以處理靜態資源,同時作為反向 Proxy把動態請求交給gunicorn處理。gunicorn負責調用我們的Python代碼,這個模型如下:

Nginx負責分發請求:

在伺服器端,我們需要定義好部署的目錄結構:

代碼如下:

/
+- srv/
+- awesome/ <-- Web App根目錄
+- www/ <-- 存放Python源碼
| +- static/ <-- 存放靜態資源檔案
+- log/ <-- 存放log

在伺服器上部署,要考慮到新版本如果運行不正常,需要回退到舊版本時怎麼辦。每次用新的代碼覆蓋掉舊的檔案是不行的,需要一個類似版本控制的機制。由於Linux系統提供了軟連結功能,所以,我們把www作為一個軟連結,它指向哪個目錄,哪個目錄就是當前啟動並執行版本:

而Nginx和gunicorn的設定檔只需要指向www目錄即可。

Nginx可以作為服務進程直接啟動,但gunicorn還不行,所以,Supervisor登場!Supervisor是一個管理進程的工具,可以隨系統啟動而啟動服務,它還時刻監控服務進程,如果服務進程意外退出,Supervisor可以自動重啟服務。

總結一下我們需要用到的服務有:

  • Nginx:高效能Web伺服器+負責反向 Proxy;
  • gunicorn:高效能WSGI伺服器;
  • gevent:把Python同步代碼變成非同步協程的庫;
  • Supervisor:監控服務進程的工具;
  • MySQL:資料庫服務。

在Linux伺服器上用apt可以直接安裝上述服務:

$ sudo apt-get install nginx gunicorn python-gevent supervisor mysql-server

然後,再把我們自己的Web App用到的Python庫安裝了:

$ sudo apt-get install python-jinja2 python-mysql.connector

在伺服器上建立目錄/srv/awesome/以及相應的子目錄。

在伺服器上初始化MySQL資料庫,把資料庫初始化指令碼schema.sql複製到伺服器上執行:

$ mysql -u root -p < schema.sql

伺服器端準備就緒。
部署

用FTP還是SCP還是rsync複製檔案?如果你需要手動複製,用一次兩次還行,一天如果部署50次不但慢、效率低,而且容易出錯。

正確的部署方式是使用工具配合指令碼完成自動化部署。Fabric就是一個自動化部署工具。由於Fabric是用Python開發的,所以,部署指令碼也是用Python來編寫,非常方便!

要用Fabric部署,需要在本機(是開發機器,不是Linux伺服器)安裝Fabric:

$ easy_install fabric

Linux伺服器上不需要安裝Fabric,Fabric使用SSH直接登入伺服器並執行部署命令。

下一步是編寫部署指令碼。Fabric的部署指令碼叫fabfile.py,我們把它放到awesome-python-webapp的目錄下,與www目錄平級:

代碼如下:

awesome-python-webapp/
+- fabfile.py
+- www/
+- ...

Fabric的指令碼編寫很簡單,首先匯入Fabric的API,設定部署時的變數:

# fabfile.pyimport os, refrom datetime import datetime# 匯入Fabric API:from fabric.api import *# 伺服器登入使用者名稱:env.user = 'michael'# sudo使用者為root:env.sudo_user = 'root'# 伺服器位址,可以有多個,依次部署:env.hosts = ['192.168.0.3']# 伺服器MySQL使用者名稱和口令:db_user = 'www-data'db_password = 'www-data'

然後,每個Python函數都是一個任務。我們先編寫一個打包的任務:

_TAR_FILE = 'dist-awesome.tar.gz'def build():  includes = ['static', 'templates', 'transwarp', 'favicon.ico', '*.py']  excludes = ['test', '.*', '*.pyc', '*.pyo']  local('rm -f dist/%s' % _TAR_FILE)  with lcd(os.path.join(os.path.abspath('.'), 'www')):    cmd = ['tar', '--dereference', '-czvf', '../dist/%s' % _TAR_FILE]    cmd.extend(['--exclude=\'%s\'' % ex for ex in excludes])    cmd.extend(includes)    local(' '.join(cmd))

Fabric提供local('...')來運行本地命令,with lcd(path)可以把當前命令的目錄設定為lcd()指定的目錄,注意Fabric只能運行命令列命令,Windows下可能需要Cgywin環境。

在awesome-python-webapp目錄下運行:

$ fab build

看看是否在dist目錄下建立了dist-awesome.tar.gz的檔案。

打包後,我們就可以繼續編寫deploy任務,把打包檔案上傳至伺服器,解壓,重設www軟連結,重啟相關服務:

_REMOTE_TMP_TAR = '/tmp/%s' % _TAR_FILE_REMOTE_BASE_DIR = '/srv/awesome'def deploy():  newdir = 'www-%s' % datetime.now().strftime('%y-%m-%d_%H.%M.%S')  # 刪除已有的tar檔案:  run('rm -f %s' % _REMOTE_TMP_TAR)  # 上傳新的tar檔案:  put('dist/%s' % _TAR_FILE, _REMOTE_TMP_TAR)  # 建立新目錄:  with cd(_REMOTE_BASE_DIR):    sudo('mkdir %s' % newdir)  # 解壓到新目錄:  with cd('%s/%s' % (_REMOTE_BASE_DIR, newdir)):    sudo('tar -xzvf %s' % _REMOTE_TMP_TAR)  # 重設軟連結:  with cd(_REMOTE_BASE_DIR):    sudo('rm -f www')    sudo('ln -s %s www' % newdir)    sudo('chown www-data:www-data www')    sudo('chown -R www-data:www-data %s' % newdir)  # 重啟Python服務和nginx伺服器:  with settings(warn_only=True):    sudo('supervisorctl stop awesome')    sudo('supervisorctl start awesome')    sudo('/etc/init.d/nginx reload')

注意run()函數執行的命令是在伺服器上運行,with cd(path)和with lcd(path)類似,把目前的目錄在伺服器端設定為cd()指定的目錄。如果一個命令需要sudo許可權,就不能用run(),而是用sudo()來執行。
配置Supervisor

上面讓Supervisor重啟gunicorn的命令會失敗,因為我們還沒有配置Supervisor呢。

編寫一個Supervisor的設定檔awesome.conf,存放到/etc/supervisor/conf.d/目錄下:

代碼如下:

[program:awesome]
command = /usr/bin/gunicorn --bind 127.0.0.1:9000 --workers 1 --worker-class gevent wsgiapp:application
directory = /srv/awesome/www
user = www-data
startsecs = 3

redirect_stderr = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups = 10
stdout_logfile = /srv/awesome/log/app.log

設定檔通過[program:awesome]指定服務名為awesome,command指定啟動gunicorn的命令列,設定gunicorn的啟動連接埠為9000,WSGI處理函數入口為wsgiapp:application。

然後重啟Supervisor後,就可以隨時啟動和停止Supervisor管理的服務了:

$ sudo supervisorctl reload$ sudo supervisorctl start awesome$ sudo supervisorctl statusawesome        RUNNING  pid 1401, uptime 5:01:34

配置Nginx

Supervisor只負責運行gunicorn,我們還需要配置Nginx。把設定檔awesome放到/etc/nginx/sites-available/目錄下:

server {  listen   80; # 監聽80連接埠  root    /srv/awesome/www;  access_log /srv/awesome/log/access_log;  error_log /srv/awesome/log/error_log;  # server_name awesome.liaoxuefeng.com; # 佈建網域名  # 處理靜態檔案/favicon.ico:  location /favicon.ico {    root /srv/awesome/www;  }  # 處理靜態資源:  location ~ ^\/static\/.*$ {    root /srv/awesome/www;  }  # 動態請求轉寄到9000連接埠(gunicorn):  location / {    proxy_pass    http://127.0.0.1:9000;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header Host $host;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  }}

然後在/etc/nginx/sites-enabled/目錄下建立軟連結:

$ pwd/etc/nginx/sites-enabled$ sudo ln -s /etc/nginx/sites-available/awesome .

讓Nginx重新載入設定檔,不出意外,我們的awesome-python-webapp應該正常運行:

$ sudo /etc/init.d/nginx reload

如果有任何錯誤,都可以在/srv/awesome/log下尋找Nginx和App本身的log。如果Supervisor啟動時報錯,可以在/var/log/supervisor下查看Supervisor的log。

如果一切順利,你可以在瀏覽器中訪問Linux伺服器上的awesome-python-webapp了:

如果在開發環境更新了代碼,只需要在命令列執行:

$ fab build$ fab deploy

自動部署完成!重新整理瀏覽器就可以看到伺服器代碼更新後的效果。
友情連結

嫌國外網速慢的童鞋請移步網易和搜狐的鏡像網站:

http://mirrors.163.com/

http://mirrors.sohu.com/

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.