Python学习笔记:Day15 部署Web App
前言
最近在學習深度學習,已經跑出了幾個模型,但Pyhton的基礎不夠扎實,因此,開始補習Python了,大家都推薦廖雪峰的課程,因此,開始了學習,但光學有沒有用,還要和大家討論一下,因此,寫下這些帖子,廖雪峰的課程連接在這里:廖雪峰
Python的相關介紹,以及它的歷史故事和運行機制,可以參見這篇:python介紹
Python的安裝可以參見這篇:Python安裝
Python的運行模式以及輸入輸出可以參見這篇:Python IO
Python的基礎概念介紹,可以參見這篇:Python 基礎
Python字符串和編碼的介紹,可以參見這篇:Python字符串與編碼
Python基本數據結構:list和tuple介紹,可以參見這篇:Python list和tuple
Python控制語句介紹:ifelse,可以參見這篇:Python 條件判斷
Python控制語句介紹:循環實現,可以參見這篇:Python循環語句
Python數據結構:dict和set介紹Python數據結構dict和set
Python函數相關:Python函數
Python高階特性:Python高級特性
Python高階函數:Python高階函數
Python匿名函數:Python匿名函數
Python裝飾器:Python裝飾器
Python偏函數:Python偏函數
Python模塊:Python模塊
Python面向對象編程(1):Python面向對象
Python面向對象編程(2):Python面向對象(2)
Python面向對象編程(3):Python面向對象(3)
Python面向對象編程(4):Pyhton面向對象(4)
Python面向對象高級編程(上):Python面向對象高級編程(上)
Python面向對象高級編程(中上):Python面向對象高級編程(中上)
Python面向對象高級編程(中下):Python面向對象高級編程(中下)
Python面向對象高級編程(完):Python面向對象高級編程(完)
Python錯誤調試(起):Python調試:起
Python錯誤調試(承):Python調試:承
Python錯誤調試(轉):Python調試:轉
Python錯誤調試(合):python調試:合
Python文件IO編程:Python文件IO
Python文件IO編程2:Python文件IO2
Python文件IO編程3:PYthon文件IO3
Python進程和線程(起):Python進程和線程起
Python進程和線程(承):Python進程和線程承
Python進程和線程(轉):Python進程和線程轉
Python進程和線程(合):Python進程和線程合
Python正則表達式:Python正則表達式
Python學習筆記:常用內建模塊1:Python學習筆記:常用內建模塊1
Python學習筆記:常用內建模塊2:Python學習筆記:常用內建模塊2
Python學習筆記:常用內建模塊3:Python學習筆記:常用內建模塊3
Python學習筆記:常用內建模塊4:Python學習筆記: 常用內建模塊4
Python學習筆記:常用內建模塊5:Python學習筆記: 常用內建模塊5
Python學習筆記:常用內建模塊6:Python學習筆記:常用內建模塊6
Python學習筆記:第三方模塊1:Python常用第三方模塊
Python學習筆記:第三方模塊2:Python常用第三方模塊
Python學習筆記:第三方模塊3:Python常用第三方模塊
Pytho學習筆記:網絡編程:Python網絡編程
Python學習筆記:電子郵件:Python電子郵件1
Python學習筆記:SMTP服務器:PythonSMTP服務器
Python學習筆記:POP3服務器:PythonPOP3服務器
Python學習筆記:Python數據庫 Python數據庫1
Python學習筆記:Python數據庫2Python數據庫2
Python學習筆記:web開發1Python學習筆記:web開發1
Python學習筆記:web開發2Python學習筆記: web開發2
Python學習筆記: web開發3Python學習筆記: web開發3
Python學習筆記:異步IO(1)Python學習筆記:異步IO(1)
Python學習筆記:異步IO(2)Python學習筆記:異步IO(2)
Python學習筆記:異步IO(3)Python學習筆記:異步IO(3)
Python學習筆記:Day 1-2開發Python學習筆記:Day1-2開發
Python學習筆記:Day 3 ORMPython學習筆記:Day3 ORM
Python學習筆記:Day 4 ModelPython學習筆記:Day4Model
Python學習筆記:Day 5 web框架PYTHON學習筆記:DAy5
Python學習筆記:Day 6 配置文件Python學習筆記:Day 6 配置文件
Python學習筆記:Day 7 編寫MVCPython學習筆記:Day 7編寫MVC
Python學習筆記:Day 8 構建前端Python學習筆記:Day 8 構建前端
Python學習筆記:Day 9 編寫APIPython 9編寫API
Python學習筆記:Day 10 用戶注冊和登陸Python 10用戶注冊和登陸
Python學習筆記:Day11 編寫日志創建頁day11 編寫目錄
Python學習筆記:Day12 編寫日志列表頁day12 編寫日志
Python學習筆記:Day13 提升開發效率開發效率
Python學習筆記:Day14 完成Web App完成web app
目錄
- 前言
- 目錄
- 部署web app
- 搭建Linux服務器
- 部署方式
- 部署
- 配置Supervisor
- 配置Nginx
部署web app
作為一個合格的開發者,在本地環境下完成開發還遠遠不夠,我們需要把Web App部署到遠程服務器上,這樣,廣大用戶才能訪問到網站。
很多做開發的同學把部署這件事情看成是運維同學的工作,這種看法是完全錯誤的。首先,最近流行devOps理念理念,就是說,開發和運維要變成一個整體。其次,運維的難度,其實跟開發質量有很大的關系。代碼寫得垃圾,運維再好也架不住天天掛掉。最后,DevOps理念需要把運維、監控等功能融入到開發中。你想服務器升級時不中斷用戶服務?那就得在開發時考慮到這一點。
下面,我們就來把awesome-python3-webapp部署到Linux服務器。
搭建Linux服務器
要部署到Linux,首先得有一臺Linux服務器。要在公網上體驗的同學,可以在Amazon的AWZ申請一臺EC2虛擬機(免費使用1年),或者使用國內的一些云服務器,一般都提供Ubuntu Server的鏡像。想在本地部署的同學,請安裝虛擬機,推薦使用VirtualBoxfile。
我們選擇的Linux服務器版本是Ubuntu server 14.04 LTS,原因是apt太簡單了。如果你準備使用其他Linux版本,也沒有問題。
Linux安裝完成后,請確保ssh服務正在運行,否則,需要通過apt安裝:
$ sudo apt-get install openssh-server有了ssh服務,就可以從本地連接到服務器上。建議把公鑰復制到服務器端用戶的.ssh/authorized_keys中,這樣,就可以通過證書實現無密碼連接。
部署方式
利用Python自帶的asyncio,我們已經編寫了一個異步高性能服務器。但是,我們還需要一個高性能的Web服務器,這里選擇Nginx,它可以處理靜態資源,同時作為反向代理把動態請求交給Python代碼處理。這個模型如下:
Nginx負責分發請求:
在服務器端,我們需要定義好部署的目錄結構:
/ +- srv/+- awesome/ <-- Web App根目錄+- www/ <-- 存放Python源碼| +- static/ <-- 存放靜態資源文件+- log/ <-- 存放log在服務器上部署,要考慮到新版本如果運行不正常,需要回退到舊版本時怎么辦。每次用新的代碼覆蓋掉舊的文件是不行的,需要一個類似版本控制的機制。由于Linux系統提供了軟鏈接功能,所以,我們把www作為一個軟鏈接,它指向哪個目錄,哪個目錄就是當前運行的版本:
而Nginx和python代碼的配置文件只需要指向www目錄即可。
Nginx可以作為服務進程直接啟動,但app.py還不行,所以,可以隨系統啟動而啟動登場!Supervisor是一個管理進程的工具,可以隨系統啟動而啟動服務,它還時刻監控服務進程,如果服務進程意外退出,Supervisor可以自動重啟服務。
總結一下我們需要用到的服務有:
?Nginx:高性能Web服務器+負責反向代理;
?Supervisor:監控服務進程的工具;
?MySQL:數據庫服務。
在Linux服務器上用apt可以直接安裝上述服務:
$ sudo apt-get install nginx supervisor python3 mysql-server然后,再把我們自己的Web App用到的Python庫安裝了:
$ sudo pip3 install jinja2 aiomysql aiohttp在服務器上創建目錄/srv/awesome/以及相應的子目錄。
在服務器上初始化MySQL數據庫,把數據庫初始化腳本schema.sql復制到服務器上執行:
$ mysql -u root -p < schema.sql服務器端準備就緒。
部署
用FTP還是SCP還是rsync復制文件?如果你需要手動復制,用一次兩次還行,一天如果部署50次不但慢、效率低,而且容易出錯。
正確的部署方式是使用工具配合腳本完成自動化部署。Fabric就是一個自動化部署工具。由于Fabric是用Python 2.x開發的,所以,部署腳本要用Python 2.7來編寫,本機還必須安裝Python 2.7版本。
要用Fabric部署,需要在本機(是開發機器,不是Linux服務器)安裝Fabric:
$ easy_install fabricLinux服務器上不需要安裝Fabric,Fabric使用SSH直接登錄服務器并執行部署命令。
下一步是編寫部署腳本。Fabric的部署腳本叫fabfile.py,我們把它放到awesome-python-webapp的目錄下,與www目錄平級:
awesome-python-webapp/ +- fabfile.py +- www/ +- ...Fabric的腳本編寫很簡單,首先導入Fabric的API,設置部署時的變量:# fabfile.py import os, re from 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重啟awesome的命令會失敗,因為我們還沒有配置Supervisor呢。
編寫一個Supervisor的配置文件awesome.conf,存放到/etc/supervisor/conf.d/目錄下:
[program:awesome]command = /srv/awesome/www/app.py directory = /srv/awesome/www user = www-data startsecs = 3redirect_stderr = true stdout_logfile_maxbytes = 50MB stdout_logfile_backups = 10 stdout_logfile = /srv/awesome/log/app.log配置文件通過[program:awesome]指定服務名為awesome,command指定啟動app.py。
然后重啟Supervisor后,就可以隨時啟動和停止Supervisor管理的服務了:
$ sudo supervisorctl reload $ sudo supervisorctl start awesome $ sudo supervisorctl status awesome RUNNING pid 1401, uptime 5:01:34配置Nginx
Supervisor只負責運行app.py,我們還需要配置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端口: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-python3-webapp應該正常運行:
$ sudo /etc/init.d/nginx reload如果有任何錯誤,都可以在/srv/awesome/log下查找Nginx
和App本身的log。如果Supervisor啟動時報錯,可以在/var/log/supervisor下查看Supervisor的
og。
如果一切順利,你可以在瀏覽器中訪問Linux服務器上的awesome-python3-webapp了:
如果在開發環境更新了代碼,只需要在命令行執行:
$ fab build $ fab deploy自動部署完成!刷新瀏覽器就可以看到服務器代碼更新后的效果。
友情鏈接
嫌國外網速慢的童鞋請移步網易和搜狐的鏡像站點:
http://mirrors.163.com/
http://mirrors.sohu.com/
總結
以上是生活随笔為你收集整理的Python学习笔记:Day15 部署Web App的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言中小数在内存中的存储,c语言中小数
- 下一篇: (转载)认知升级