阿里云部署Ubuntu 1.4 Flask + WSGI + Nginx 詳解
抵不住朋友的誘惑,今天終于入手了一臺(tái)阿里云服務(wù)器,是Ubuntu 1.4 32位版本,最初考慮是用來(lái)嘗嘗鮮只是買了個(gè)最低配的,價(jià)格算起來(lái)與在國(guó)外買個(gè)空間的價(jià)格相當(dāng)吧(可能一年才貴100多),但用起來(lái)感覺(jué)就很不錯(cuò),速度那是一個(gè)字:快。
自從倒戈向Linux世界后,對(duì)于一切大而全的開(kāi)發(fā)框架與軟件都有一種不討喜的感覺(jué),個(gè)人更喜歡于使用那些小而精,高性能高產(chǎn)生力的軟件和開(kāi)發(fā)框架,So 我現(xiàn)在的第一語(yǔ)言是Python和Coffee,開(kāi)發(fā)框架就當(dāng)然是 AngularJS (前端) + Flask (后端) ,關(guān)于 AngularJS 與 Flask 不在本文的敘述范圍之內(nèi),本文解決的是 Flask 最后一公里的問(wèn)題:Linux 部署。
我采用的部署方案是:
- Web 服務(wù)器采用 uwsgi host Flask
- 用 Supervisor 引用 uwsgi 作常規(guī)啟動(dòng)服務(wù)
- 基于 Nginx 作反向代理
首先, 阿里云服務(wù)器可以通過(guò) SSH 指令在本機(jī)的終端進(jìn)行遠(yuǎn)程連接
ssh root@云服務(wù)器地址
輸入密碼進(jìn)入后所有的操作與本地終端完全一至。
安裝 Python 環(huán)境
接下來(lái)是python , Ubuntu 的默認(rèn)環(huán)境已經(jīng)預(yù)裝 python 2.7 所以只需要安裝 python 的 pip 安裝工具即可。pip 用于安裝一些基于python 應(yīng)用的軟件工具,在下文中將會(huì)頻繁使用。
PIP
如果用python 而不懂 [pip|http://pypi.python.org/] 那最好就快點(diǎn)腦補(bǔ)吧, 指令如下:
sudo apt-get install pip
不同的項(xiàng)目可能會(huì)引用各種不同的依賴包,為了避免版本與和應(yīng)用之間的沖突而造成的“依賴地獄”
[Virtualenv | https://virtualenv.readthedocs.org/en/latest/] 就是我們python 項(xiàng)目的必須品了。VirtualEnv 可以為每個(gè)Python應(yīng)用創(chuàng)建獨(dú)立的開(kāi)發(fā)環(huán)境,使他們互不影響,Virtualenv 能夠做到:
- 在沒(méi)有權(quán)限的情況下安裝新套件
- 不同應(yīng)用可以使用不同的套件版本
- 套件升級(jí)不影響其他應(yīng)用
安裝:
sudo pip install virtualenv
安裝VirtualEnv 后只需要在項(xiàng)目目錄內(nèi)運(yùn)行 virtualenv
目錄名 就可以建立一個(gè)虛擬環(huán)境文件夾,然后啟用 activate
指令即可啟用該python虛擬環(huán)境,具體操作如下:
假定我的項(xiàng)目目錄叫 /home/www/my_flask
,首先安裝虛擬環(huán)境 (我習(xí)慣使用的虛擬環(huán)境目錄叫 venv )
my_flask root$ virtualenv venv >> New python executable in venv/bin/python >> Installing setuptools, pip...done.
在項(xiàng)目目錄下就會(huì)建立一個(gè)新的 venv 目錄,里面就是運(yùn)行python 的基本環(huán)境的工具與指令,和包。 然后啟用該環(huán)境,使用當(dāng)前命令行狀態(tài)進(jìn)入虛擬環(huán)境,進(jìn)入虛擬環(huán)境后,一切安裝python的操作都會(huì)將包和引用裝在虛擬環(huán)境內(nèi),而不會(huì)影響到全局的python 環(huán)境。
my_flask root$ source venv/bin/activate (venv)my_flask root$
調(diào)用 activate
指令后命令符前就會(huì)出現(xiàn) (venv) 字樣。 可通過(guò) deactivate 退出虛擬環(huán)境。
安裝 uWSGI
Flask 的實(shí)際生產(chǎn)運(yùn)行環(huán)境選擇并不多,比較成熟的是 [Gunicorn|http://gunicorn.org/] 和 [uWSGI|https://github.com/unbit/uwsgi] ,聽(tīng)說(shuō)Gunicorn 的配置很簡(jiǎn)單,但可惜我一直沒(méi)有配置成功過(guò),我現(xiàn)采用的是 uWSGI。接下來(lái)就安裝uWSGI吧。
(venv)my_flask root$ pip install uwsgi
在虛擬環(huán)境下不需要使用 sudo
,因?yàn)関irtualenv 是沒(méi)有權(quán)限要求的。
這個(gè)安裝很迅速,基本是秒成。安裝完成后我們可以先放下 uWSGI 不表,在后面再回過(guò)來(lái)配置他,因?yàn)槲覀兪紫纫獙㈥P(guān)鍵的 Flask環(huán)境和我們的項(xiàng)目文件傳到服務(wù)器目錄內(nèi)。
安裝 Flask
我是用清單文件一次性安裝Flask和他的相關(guān)依賴的,這樣會(huì)更快。我的引用清單是這樣的:
requirements.txt
Flask==0.10.1 Flask-Login==0.2.11 Flask-Mail==0.9.1 Flask-Moment==0.4.0 Flask-PageDown==0.1.5 Flask-SQLAlchemy==2.0 Flask-Script==2.0.5 Flask-WTF==0.10.2 Flask-Cache==0.13.1 Flask-Restless==0.15.0 Flask-Uploads==0.1.3 Jinja2==2.7.3 Mako==1.0.0 Markdown==2.5.1 MarkupSafe==0.23 SQLAlchemy==0.9.8 WTForms==2.0.1 Werkzeug==0.9.6 html5lib==1.0b3 itsdangerous==0.24 six==1.8.0 awesome-slugify==1.6
可以想像,如果一個(gè)一個(gè)裝非瘋了不可。
安裝清單文件:
(venv)my_flask root$ pip install -r requirements.txt
在此還是重重地提一下:一定要注意在運(yùn)行這個(gè)安裝之前啟用了python 虛擬環(huán)境,否則會(huì)直接安裝到全局去的!
項(xiàng)目文件
接下來(lái)就是上傳 Flask的項(xiàng)目文件,之前我在各大的“轉(zhuǎn)載專業(yè)戶”里找了好多的資料,在這一步中大多只是在上面加個(gè)標(biāo)準(zhǔn)的Flask運(yùn)行文件,雖說(shuō)做個(gè)范例可以但說(shuō)實(shí)在的這很讓人迷惑,為什么?先看看代碼吧:
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!"
生產(chǎn)環(huán)境內(nèi),誰(shuí)會(huì)用這樣的代碼呢,這只是Flask 的最簡(jiǎn)入門范,我的Flask項(xiàng)目中 app 是被做在包內(nèi)的,相信很多人都是這樣做的,在包外我們采用 Flask Script 寫一個(gè) manage.py 文件 作為啟動(dòng)文件,這更方便于支持各種的項(xiàng)目,包括可以安裝到 window下的 FastCGI 中。
那么我的 這個(gè) manage.py 是這個(gè)樣子的:
#!/usr/bin/env python import os if os.path.exists('.env'): print('Importing environment from .env...') for line in open('.env'): var = line.strip().split('=') if len(var) == 2: os.environ[var[0]] = var[1] from app import create_app from flask.ext.script import Manager, Shell # 通過(guò)配置創(chuàng)建 app app = create_app(os.getenv('FLASK_CONFIG') or 'default') manager = Manager(app) def make_shell_context(): return dict(app=app) manager.add_command("shell", Shell(make_context=make_shell_context)) @manager.command def deploy(): """Run deployment tasks.""" pass if __name__ == '__main__': manager.run()
這樣做我地開(kāi)發(fā)環(huán)境可以這樣運(yùn)行 Flask:
python manage.py runserver
更詳細(xì)的做法請(qǐng)參考 [Flask Script|http://flask-script.readthedocs.org/en/latest/] 擴(kuò)展
好吧,我們可以用 支持SSH的FTP工具將Flask項(xiàng)目文件上傳到服務(wù)器上,下面是整個(gè)項(xiàng)目文件結(jié)構(gòu):
www/ └── my_flask │ ├── logs │ └── venv //虛擬目錄 │ │ ├── bin │ │ │ ├── activate │ │ │ ├── easy_install │ │ │ ├── gunicorn │ │ │ ├── pip │ │ │ └── python │ │ ├── include │ │ │ └── python2.7 -> /usr/include/python2.7 │ │ ├── lib │ │ │ └── python2.7 │ │ ├── local │ │ │ ├── bin -> /home/shenye/shenyefuli/bin │ │ │ ├── include -> /home/shenye/shenyefuli/include │ │ │ └── lib -> /home/shenye/shenyefuli/lib │ └── app //Flask 程序目錄 │ │ └── __init__.py //這是程序包文件。這個(gè)目錄下還有其它的文件此處略過(guò) │ ├── manage.py │ ├── requirements.txt
配置 uwsgi
好了,項(xiàng)目的準(zhǔn)備工作已經(jīng)做完了,是時(shí)候回過(guò)頭去配置 uwsgi 了,它的具體指令可以去看它的官方文檔,我們?cè)谶@里采用其中的一種指令方式:配置起動(dòng)。我采用 .ini文件作為配置,在項(xiàng)目目錄下創(chuàng)建一個(gè) confg.ini (具體見(jiàn)下文)寫好后可以這樣執(zhí)行
(venv)my_flask root$ uwsgi config.ini
我認(rèn)為是最簡(jiǎn)單的方式,也容易更改。好了重要部分來(lái)了,config.ini 是這樣寫的:
[uwsgi] # uwsgi 啟動(dòng)時(shí)所使用的地址與端口 socket = 127.0.0.1:8001 # 指向網(wǎng)站目錄 chdir = /home/www/ # python 啟動(dòng)程序文件 wsgi-file = manage.py # python 程序內(nèi)用以啟動(dòng)的 application 變量名 callable = app # 處理器數(shù) processes = 4 # 線程數(shù) threads = 2 #狀態(tài)檢測(cè)地址 stats = 127.0.0.1:9191
注意 : callable=app 這個(gè) app 是 manage.py 程序文件內(nèi)的一個(gè)變量,這個(gè)變量的類型是 Flask的 application 類 。
運(yùn)行 uwsgi
```
(venv)my_flask root$ uwsgi config.ini
[uWSGI] getting INI configuration from config.ini
*** Starting uWSGI 2.0.8 (64bit) on [Fri Dec 19 14:34:11 2014]
// 此處略去那些無(wú)用的啟動(dòng)信息
Stats server enabled on 127.0.0.1:9191 fd: 15 ***
```
OK, 此時(shí)已經(jīng)正常啟動(dòng) uwsgi 并將 Flask 項(xiàng)目載入其中了,ctrl+c 關(guān)閉程序。但這只是命令啟動(dòng)形式,要使其隨同服務(wù)器啟動(dòng)并作為后臺(tái)服務(wù)運(yùn)行才是運(yùn)營(yíng)環(huán)境的實(shí)際所需要。因此接下來(lái)我們需要安裝另一個(gè)工具來(lái)引導(dǎo) uwsgi 。
安裝 Supervisor
[Supervisor|http://supervisord.org/configuration.html]可以同時(shí)啟動(dòng)多個(gè)應(yīng)用,最重要的是,當(dāng)某個(gè)應(yīng)用Crash的時(shí)候,他可以自動(dòng)重啟該應(yīng)用,保證可用性。
sudo apt-get install supervisor
Supervisor 的全局的配置文件位置在:
/etc/supervisor/supervisor.conf
正常情況下我們并不需要去對(duì)其作出任何的改動(dòng),只需要添加一個(gè)新的 *.conf 文件放在
/etc/supervisor/conf.d/
下就可以,那么我們就新建立一個(gè)用于啟動(dòng) my_flask 項(xiàng)目的 uwsgi 的 supervisor 配置 (命名為:my_flask_supervisor.conf):
[program:my_flask] # 啟動(dòng)命令入口 command=/home/www/my_flask/venv/bin/uwsgi /home/www/my_flask/config.ini # 命令程序所在目錄 directory=/home/www/my_flask #運(yùn)行命令的用戶名 user=root autostart=true autorestart=true #日志地址 stdout_logfile=/home/www/my_flask/logs/uwsgi_supervisor.log
啟動(dòng)服務(wù)
sudo service supervisor start
終止服務(wù)
sudo service supervisor stop
安裝 Nginx
[Nginx|http://nginx.com/]是輕量級(jí)、性能強(qiáng)、占用資源少,能很好的處理高并發(fā)的反向代理軟件。
sudo apt-get install nginx
配置 Nginx
Ubuntu 上配置 Nginx 也是很簡(jiǎn)單,不要去改動(dòng)默認(rèn)的 nginx.conf 只需要將
/ext/nginx/sites-available/default
文件替換掉就可以了。
新建一個(gè) default 文件:
server { listen 80; server_name XXX.XXX.XXX; #公網(wǎng)地址 location / { include uwsgi_params; uwsgi_pass 127.0.0.1:8001; # 指向uwsgi 所應(yīng)用的內(nèi)部地址,所有請(qǐng)求將轉(zhuǎn)發(fā)給uwsgi 處理 uwsgi_param UWSGI_PYHOME /home/www/my_flask/venv; # 指向虛擬環(huán)境目錄 uwsgi_param UWSGI_CHDIR /home/www/my_flask; # 指向網(wǎng)站根目錄 uwsgi_param UWSGI_SCRIPT manage:app; # 指定啟動(dòng)程序 } }
將default配置文件替換掉就大功告成了!
還有,更改配置還需要記得重啟一下nginx:
sudo service nginx restart
總結(jié)
阿里云的服務(wù)器運(yùn)行速度很不錯(cuò),加上Flask+uWSGI+nginx 這種高性能結(jié)構(gòu),整個(gè)網(wǎng)站響應(yīng)速度極為之快,每頁(yè)響應(yīng)速度不到0.1s , 與之相比我之前使用 C# 部署在Avarix 上的網(wǎng)站(同一個(gè)程序,不同語(yǔ)言實(shí)現(xiàn))每頁(yè)響應(yīng)速度至少2s 這簡(jiǎn)直是 200:1的性能,當(dāng)然我還沒(méi)有閑到去專們用軟件去測(cè)這兩者之間的差值,寫本文的目的也是對(duì)此作一記錄,以便以后回顧。
- IIS服務(wù)器配置阿里云https(SSL)證書的方法
- 阿里云申請(qǐng)?jiān)贫苊赓M(fèi)SSL證書(https)
- 阿里云負(fù)載均衡SLB安裝SSL證書的方法
- 阿里云服務(wù)器apache配置SSL證書成功開(kāi)啟Https(記錄趟過(guò)的各種坑)
- 阿里云部署SSL證書詳解
- Vue項(xiàng)目部署的實(shí)現(xiàn)(阿里云+Nginx代理+PM2)
- 結(jié)合 Nginx 將 DoNetCore 部署到 阿里云的安裝配置方法
- 利用nginx + node在阿里云部署https的步驟詳解
- 阿里云ssl證書如何通過(guò)Nginx部署到服務(wù)器
相關(guān)文章
Nginx實(shí)現(xiàn)會(huì)話保持的兩種方式
在我們做Nginx負(fù)載均衡的時(shí)候經(jīng)常會(huì)遇到會(huì)話保持的問(wèn)題,為了保證同一用戶session會(huì)被分配到同一臺(tái)服務(wù)器上,這時(shí)就需要會(huì)話保持,本文介紹了兩種方法,感興趣的可以了解一下2022-03-03nginx使用內(nèi)置模塊配置限速限流的方法實(shí)例
Nginx現(xiàn)在已經(jīng)是最火的負(fù)載均衡之一,在流量陡增的互聯(lián)網(wǎng)面前,接口限流也是很有必要的,尤其是針對(duì)高并發(fā)的場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于nginx使用內(nèi)置模塊配置限速限流的相關(guān)資料,需要的朋友可以參考下2022-05-05Nginx實(shí)現(xiàn)請(qǐng)求的超時(shí)自動(dòng)重試的方法示例
在當(dāng)今數(shù)字化的快節(jié)奏世界中,我們的網(wǎng)絡(luò)應(yīng)用就像是繁忙的交通樞紐,每天都要處理海量的請(qǐng)求,我們需要一種像“備用路線”一樣的機(jī)制,也就是請(qǐng)求的超時(shí)自動(dòng)重試,本文就給大家介紹了Nginx?中怎樣實(shí)現(xiàn)請(qǐng)求的超時(shí)自動(dòng)重試,需要的朋友可以參考下2024-07-07nginx關(guān)閉favicon.ico、robots.txt日志記錄配置
這篇文章主要介紹了nginx關(guān)閉favicon.ico、robots.txt日志記錄配置,同時(shí)提供了不允許訪問(wèn)某些隱藏文件的配置方法,需要的朋友可以參考下2014-05-05Nginx下WordPress鏈接(url偽靜態(tài))301永久重定向?qū)崿F(xiàn)方法
在幾個(gè)blog程序中折騰的結(jié)果,導(dǎo)致url連續(xù)二次變化。這是第三次了。 nginx 通過(guò)rewrite 使用 permanent; 參數(shù) 成301永久url重定向2012-09-09