Linux下部署Flask項目——Ubuntu+Flask+Gunicorn+Supervisor+Nginx
Ubuntu16.04+Anaconda2+nginx+gunicorn+flask+supervisor
概述:
把Python的Flask框架開發的Web應用,在Ubuntu上用gunicorn部署起來,用supervisor實現進程守護,用nginx實現代理和負載均衡。其中的python使用的是anaconda2 這個集成包里的。並在anaconda創建的虛擬環境中運行應用。關於虛擬環境的解釋見下文。
當然,你也可以不用創建虛擬環境,直接在個人用戶下執行,只需將下文中虛擬環境部分改在真實環境中執行即可。
第一步:安裝anaconda2
-
1.1,下載Anaconda2的.sh安裝包
Anaconda的官網在這裡Download Anaconda Now!。與Python相對應,Anaconda的版本分為Anaconda2和Anaconda3,大家可以自行下載日常常用的版本,提供32位和64位下載。但下載速度太慢,建議用國內鏡像:
下載地址 Index of /anaconda/archive/選擇相應的版本進行下載就好。linux 下載下來是一個*.sh文件
-
1.2,安裝anaconda並配置源
安裝Anaconda建議不要用root用戶,即安裝在自己的個人家目錄下即可:
bash *.sh
安裝一路按確認Yes即可。安裝完成之後會在家目錄下出現文件夾:
~/Anaconda2/ (以anaconda2為例)
注意安裝過程中最後會問是否配置環境變數,記得選擇yes,如果錯過了,則需要手動配置環境變數
echo 『export PATH="~/anaconda2/bin:$PATH"』 > ~/.bashrcsource ~/.bashrc
在anaconda中,conda install 命令也可以下載python庫,類似於pip
首先,由於默認的源地址在國外較慢,我們需要修改其包管理鏡像為國內源。Tsinghua Open Source Mirror簡單來說就是在終端中運行這兩個命令就好了:conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --set show_channel_urls yes
執行完上述命令後,會生成~/.condarc(Linux/Mac)或C:UsersUSER_NAME.condarc文件,記錄著我們對conda的配置,直接手動創建、編輯該文件是相同的效果。
而pip的源修改如下:修改~/.pip/pip.conf,沒有則創建[global]index-url = http://pypi.douban.com/simpletrusted-host = pypi.douban.comtimeout = 120
第二步:用anaconda開啟一個虛擬環境
虛擬環境是一個將不同項目所需求的依賴分別放在獨立的地方的一個工具,它給這些工程創建虛擬的Python環境。它解決了「項目X依賴於版本1.x,而項目Y需要項目4.x」的兩難問題,而且使你的全局site-packages目錄保持乾淨和可管理。比如,你可以工作在一個需求Django 1.3的工程,同時維護一個需求Django 1.0的工程。
-
2.1,創建虛擬環境
python中可以用virtualenv創建虛擬環境,而我們安裝的anaconda也有這個功能,創建一個名為 test1 的虛擬環境,並為這個虛擬環境添加flask庫
conda create -n test1 flask
-
2.2,激活虛擬環境
source activate test1
進入虛擬環境之後,命令行用戶名前會出現一個括弧,括弧內是該虛擬環境的名字,表示這是在虛擬環境中
第三步:用flask框架構建一個簡單的web應用
新建一個目錄,webtest1,內新建一個python文件webtest.py
新建py文件#!/usr/bin/env python# -*- coding: utf-8 -*-#webtest.pyfrom flask import Flask,requestapp = Flask(__name__)@app.route(/)def home(): return "home"if __name__ == __main__: app.run(debug=False)
此時運行該py文件,即開啟了該web應用,如圖所示,輸入http://127.0.0.1:5000/,即可顯示home界面
直接python運行成功此時,只能本地訪問,如果要實現區域網訪問,則需修改webtest.py:
#!/usr/bin/env python# -*- coding: utf-8 -*-#webtest.pyfrom flask import Flask,requestapp = Flask(__name__)@app.route(/)def home(): return "home"if __name__ == __main__: app.debug=False app.run(host=0.0.0.0)
此時,在同區域網的電腦瀏覽器中輸入運行該代碼的機器ip:5000,則顯示home界面
區域網瀏覽器瀏覽結果截止這一步,其實我們簡單完成了webapi的部署。下面的步驟都是輔助性的,目的在於提高性能,讓這個web應用不容易崩。
第四步:安裝運行gunicorn
gunicorn是一個WSGI伺服器,類似於JAVA中的tomcat。上一步中我們使用的是flask 自帶的伺服器,完成了 web 服務的啟動。生產環境下,flask 自帶的伺服器,無法滿足性能要求。我們這裡採用 gunicorn 做 wsgi容器,用來部署 python。
-
4.1,在虛擬環境下安裝gunicorn
pip install gunicorn
-
4.2,用gunicorn運行web應用
gunicorn tmp/webtest1/webtest:app
webtest對應的是py文件名,app對應的是文件中Flask的實現名,這裡默認開啟的是8000埠。
我這裡使用了-b 0.0.0.0:8001 指定了埠,因為默認的8000埠已被佔用
此時訪問結果如下瀏覽器結果第五步:安裝配置nginx
什麼是nginx,nginx和gunicorn的區別
nginx是一個 HTTP 伺服器, 它關心的是 HTTP 協議層面的傳輸和訪問控制,所以在 Apache/Nginx 上你可以看到代理、負載均衡等功能。客戶端通過 HTTP Server 訪問伺服器上存儲的資源(HTML 文件、圖片文件等等)。通過 CGI 技術,也可以將處理過的內容通過 HTTP Server 分發,但是一個 HTTP Server 始終只是把伺服器上的文件如實的通過 HTTP 協議傳輸給客戶端。
而上面所說的gunicorn,是應用伺服器,是一個應用執行的容器。它首先需要支持開發語言的 Runtime(對於 Tomcat 來說就是 Java,對gunicorn來說就是python),保證應用能夠在應用伺服器上正常運行。其次,需要支持應用相關的規範,例如類庫、安全方面的特性。對於 Tomcat 來說,就是需要提供 JSP/Sevlet 運行需要的標準類庫、Interface 等。為了方便,應用伺服器往往也會集成 HTTP Server 的功能,但是不如專業的 HTTP Server 那麼強大,所以應用伺服器往往是運行在 HTTP Server 的背後,執行應用,將動態的內容轉化為靜態的內容之後,通過 HTTP Server 分發到客戶端。
作者:Leh鏈接:https://www.zhihu.com/question/32212996/answer/55169095來源:知乎著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處
-
5.1,安裝nginx
sudo apt-get install nginx
nginx的配置文件在 /etc/nginx/sites-available/里,默認的是default文件,如果沒有,則創建default。
server {
listen 80; server_name 127.0.0.1; location / { try_files $uri @gunicorn_proxy; } location @gunicorn_proxy { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://127.0.0.1:8000; proxy_connect_timeout 500s; proxy_read_timeout 500s; proxy_send_timeout 500s; }}
-
5.2,啟動nginx或重啟nginx (restart)
service nginx start
第六步:supervisor進程守護
嚴重推薦這篇介紹 :使用 supervisor 管理進程
Supervisor (http://supervisord.org) 是一個用 Python 寫的進程管理工具,可以很方便的用來啟動、重啟、關閉進程(不僅僅是 Python 進程)。
除了對單個進程的控制,還可以同時啟動、關閉多個進程,比如很不幸的伺服器出問題導致所有應用程序都被殺死,此時可以用 supervisor 同時啟動所有應用程序而不是一個一個地敲命令啟動。
-
6.1,安裝supervisor(不在虛擬環境里)
pip install supervisor 或者使用 sudo apt-get install supervisor
-
6.2,配置文件 supervisor.conf
用以下命令可以把默認的配置生成到制定位置
echo_supervisord_conf > /your_file_path/supervisord.conf
如果是使用apt-get安裝的,那麼 這個supervisord.conf文件會在 /etc/supervisor/文件夾下自動生成
; supervisor config file[unix_http_server]file=/var/run/supervisor.sock ; (the path to the socket file)chmod=0700 ; sockef file mode (default 0700)[supervisord]logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)childlogdir=/var/log/supervisor ; (AUTO child log dir, default $TEMP)[rpcinterface:supervisor]supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface[supervisorctl]serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket[include]files = /etc/supervisor/conf.d/*.conf
配置文件最後一行,設置的是要運行的進程的配置文件路徑,可見只要後綴名是conf即可被識別,於是新建文件/etc/supervisor/conf.d/webapi.conf
[program:webtest]directory = /home/bigdata/Project_2017/webapi/ ; 程序的啟動目錄command =/home/bigdata/anaconda2/bin/gunicorn -k gevent -t 300 run:app ; 啟動命令,可以看出與手動在命令行啟動的命令是一樣的autostart = true ; 在 supervisord 啟動的時候也自動啟動startsecs = 5 ; 啟動 5 秒後沒有異常退出,就當作已經正常啟動了autorestart = true ; 程序異常退出後自動重啟startretries = 3 ; 啟動失敗自動重試次數,默認是 3user = root ; 用哪個用戶啟動redirect_stderr = true ; 把 stderr 重定向到 stdout,默認 falsestdout_logfile_maxbytes = 20MB ; stdout 日誌文件大小,默認 50MBstdout_logfile_backups = 20 ; stdout 日誌文件備份數; stdout 日誌文件,需要注意當指定目錄不存在時無法正常啟動,所以需要手動創建目錄(supervisord 會自動創建日誌文件)stdout_logfile = /home/bigdata/tmp/usercenter_stdout.log; 可以通過 environment 來添加需要的環境變數,一種常見的用法是修改 PYTHONPATH; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere
自行修改以上配置
-
6.3,設置並啟動supervisord(服務端)
首先,supervisord運行是需要有配置文件的,啟動supervisord可以直接命令行運行
supervisord
這時,supervisor會默認依次在這幾個路徑下尋找配置文件$CWD/supervisord.conf, $CWD/etc/supervisord.conf, /etc/supervisord.conf
如果這幾個路徑下沒有該配置文件,則啟動失敗。所以如果配置文件在其他位置例如/your_file_path/supervisord.conf ,則需要用 -c 設置supervisord -c /your_file_path/supervisord.conf
-
6.4,啟動supervisorctl(客戶端)
sudo supervisorctl -c /your_file_path/supervisord.conf
這裡客戶端和服務端要使用同一個supervisord.conf文件,要確保兩者使用的是同一個!要麼都默認位置,要麼都指定同一位置。這樣就可以進入supervisor客戶端
Supervisor客戶端
這裡的web應用是對應的/etc/supervisor/conf.d/webapi.conf文件里的配置的,我的配置文件有兩個即
webapp 和 webtest這樣,web介面進程就被supervisor守護了,關掉終端也無所謂了。如果要關閉應用進程,則進入supervisorctl
裡面有stop;start;restart等命令,後跟web應用名即可參考文獻:
https://zhuanlan.zhihu.com/p/21262280
python web 部署:nginx + gunicorn + supervisor + flask 部署筆記https://gist.github.com/binderclip/f6b6f5ed4d71fa64c7c5
http://www.cnblogs.com/Ray-liang/p/4837850.htmlhttp://liyangliang.me/posts/2015/06/using-supervisor/https://www.zhihu.com/question/32212996PS:錯誤之處還請指正,謝謝!
推薦閱讀:
※有c#基礎,最近對爬蟲感興趣,開始轉學python,求指導?
※python爬蟲——寫出最簡單的網頁爬蟲
※《Python數據挖掘》筆記(三)實體匹配
※小心了!小白無法入門Python你不可避免的4個陷阱
※在 Pycom 使用 Python + Micropython + MQTT 進行物聯網編程