Linux下部署Flask項(xiàng)目——Ubuntu+Flask+Gunicorn+Supervisor+Nginx

Ubuntu16.04+Anaconda2+nginx+gunicorn+flask+supervisor

概述:

把Python的Flask框架開(kāi)發(fā)的Web應(yīng)用,在Ubuntu上用gunicorn部署起來(lái),用supervisor實(shí)現(xiàn)進(jìn)程守護(hù),用nginx實(shí)現(xiàn)代理和負(fù)載均衡。其中的python使用的是anaconda2 這個(gè)集成包里的。并在anaconda創(chuàng)建的虛擬環(huán)境中運(yùn)行應(yīng)用。關(guān)于虛擬環(huán)境的解釋見(jiàn)下文。

當(dāng)然,你也可以不用創(chuàng)建虛擬環(huán)境,直接在個(gè)人用戶下執(zhí)行,只需將下文中虛擬環(huán)境部分改在真實(shí)環(huán)境中執(zhí)行即可。

第一步:安裝anaconda2

  • 1.1,下載Anaconda2的.sh安裝包

Anaconda的官網(wǎng)在這里Download Anaconda Now!。與Python相對(duì)應(yīng),Anaconda的版本分為Anaconda2和Anaconda3,大家可以自行下載日常常用的版本,提供32位和64位下載。但下載速度太慢,建議用國(guó)內(nèi)鏡像:
下載地址 Index of /anaconda/archive/選擇相應(yīng)的版本進(jìn)行下載就好。
linux 下載下來(lái)是一個(gè)*.sh文件

  • 1.2,安裝anaconda并配置源

安裝Anaconda建議不要用root用戶,即安裝在自己的個(gè)人家目錄下即可:

  bash *.sh

安裝一路按確認(rèn)Yes即可。安裝完成之后會(huì)在家目錄下出現(xiàn)文件夾:

  ~/Anaconda2/ (以anaconda2為例)

注意安裝過(guò)程中最后會(huì)問(wèn)是否配置環(huán)境變量,記得選擇yes,如果錯(cuò)過(guò)了,則需要手動(dòng)配置環(huán)境變量

  echo ‘export PATH="~/anaconda2/bin:$PATH"’ > ~/.bashrc
  source ~/.bashrc

在anaconda中,conda install 命令也可以下載python庫(kù),類似于pip
首先,由于默認(rèn)的源地址在國(guó)外較慢,我們需要修改其包管理鏡像為國(guó)內(nèi)源。
Tsinghua Open Source Mirror
簡(jiǎn)單來(lái)說(shuō)就是在終端中運(yùn)行這兩個(gè)命令就好了:

  conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
  conda config --set show_channel_urls yes

執(zhí)行完上述命令后,會(huì)生成~/.condarc(Linux/Mac)或C:\Users\USER_NAME.condarc文件,記錄著我們對(duì)conda的配置,直接手動(dòng)創(chuàng)建、編輯該文件是相同的效果。
而pip的源修改如下:修改~/.pip/pip.conf,沒(méi)有則創(chuàng)建

[global]
index-url = http://pypi.douban.com/simple
trusted-host = pypi.douban.com
timeout = 120

第二步:用anaconda開(kāi)啟一個(gè)虛擬環(huán)境

虛擬環(huán)境是一個(gè)將不同項(xiàng)目所需求的依賴分別放在獨(dú)立的地方的一個(gè)工具,它給這些工程創(chuàng)建虛擬的Python環(huán)境。它解決了“項(xiàng)目X依賴于版本1.x,而項(xiàng)目Y需要項(xiàng)目4.x”的兩難問(wèn)題,而且使你的全局site-packages目錄保持干凈和可管理。比如,你可以工作在一個(gè)需求Django 1.3的工程,同時(shí)維護(hù)一個(gè)需求Django 1.0的工程。

  • 2.1,創(chuàng)建虛擬環(huán)境

python中可以用virtualenv創(chuàng)建虛擬環(huán)境,而我們安裝的anaconda也有這個(gè)功能,創(chuàng)建一個(gè)名為 test1 的虛擬環(huán)境,并為這個(gè)虛擬環(huán)境添加flask庫(kù)

   conda create -n test1 flask
Anaconda創(chuàng)建虛擬環(huán)境
  • 2.2,激活虛擬環(huán)境

    source activate test1
    
激活虛擬環(huán)境

進(jìn)入虛擬環(huán)境之后,命令行用戶名前會(huì)出現(xiàn)一個(gè)括號(hào),括號(hào)內(nèi)是該虛擬環(huán)境的名字,表示這是在虛擬環(huán)境中

第三步:用flask框架構(gòu)建一個(gè)簡(jiǎn)單的web應(yīng)用

新建一個(gè)目錄,webtest1,內(nèi)新建一個(gè)python文件webtest.py

新建py文件

直接vim編輯

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#webtest.py

from flask import Flask,request
app = Flask(__name__)

@app.route('/')
def home():
    return "home"
if __name__ == '__main__':
    app.run(debug=False)

此時(shí)運(yùn)行該py文件,即開(kāi)啟了該web應(yīng)用,如圖所示,輸入http://127.0.0.1:5000/,即可顯示home界面

直接python運(yùn)行成功

此時(shí),只能本地訪問(wèn),如果要實(shí)現(xiàn)局域網(wǎng)訪問(wèn),則需修改webtest.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#webtest.py

from flask import Flask,request
app = Flask(__name__)

@app.route('/')
def home():
    return "home"
if __name__ == '__main__':
    app.debug=False
    app.run(host='0.0.0.0')

此時(shí),在同局域網(wǎng)的電腦瀏覽器中輸入運(yùn)行該代碼的機(jī)器ip:5000,則顯示home界面

局域網(wǎng)瀏覽器瀏覽結(jié)果

截止這一步,其實(shí)我們簡(jiǎn)單完成了webapi的部署。下面的步驟都是輔助性的,目的在于提高性能,讓這個(gè)web應(yīng)用不容易崩。

第四步:安裝運(yùn)行g(shù)unicorn

gunicorn是一個(gè)WSGI服務(wù)器,類似于JAVA中的tomcat。上一步中我們使用的是flask 自帶的服務(wù)器,完成了 web 服務(wù)的啟動(dòng)。生產(chǎn)環(huán)境下,flask 自帶的服務(wù)器,無(wú)法滿足性能要求。我們這里采用 gunicorn 做 wsgi容器,用來(lái)部署 python。

  • 4.1,在虛擬環(huán)境下安裝gunicorn

    pip install gunicorn
    
  • 4.2,用gunicorn運(yùn)行web應(yīng)用

    gunicorn tmp/webtest1/webtest:app
    

    webtest對(duì)應(yīng)的是py文件名,app對(duì)應(yīng)的是文件中Flask的實(shí)現(xiàn)名,這里默認(rèn)開(kāi)啟的是8000端口。

Gunicorn運(yùn)行

我這里使用了-b 0.0.0.0:8001 指定了端口,因?yàn)槟J(rèn)的8000端口已被占用
此時(shí)訪問(wèn)結(jié)果如下

瀏覽器結(jié)果

第五步:安裝配置nginx

什么是nginx,nginx和gunicorn的區(qū)別

nginx是一個(gè) HTTP 服務(wù)器, 它關(guān)心的是 HTTP 協(xié)議層面的傳輸和訪問(wèn)控制,所以在 Apache/Nginx 上你可以看到代理、負(fù)載均衡等功能??蛻舳送ㄟ^(guò) HTTP Server 訪問(wèn)服務(wù)器上存儲(chǔ)的資源(HTML 文件、圖片文件等等)。通過(guò) CGI 技術(shù),也可以將處理過(guò)的內(nèi)容通過(guò) HTTP Server 分發(fā),但是一個(gè) HTTP Server 始終只是把服務(wù)器上的文件如實(shí)的通過(guò) HTTP 協(xié)議傳輸給客戶端。
而上面所說(shuō)的gunicorn,是應(yīng)用服務(wù)器,是一個(gè)應(yīng)用執(zhí)行的容器。它首先需要支持開(kāi)發(fā)語(yǔ)言的 Runtime(對(duì)于 Tomcat 來(lái)說(shuō)就是 Java,對(duì)gunicorn來(lái)說(shuō)就是python),保證應(yīng)用能夠在應(yīng)用服務(wù)器上正常運(yùn)行。其次,需要支持應(yīng)用相關(guān)的規(guī)范,例如類庫(kù)、安全方面的特性。對(duì)于 Tomcat 來(lái)說(shuō),就是需要提供 JSP/Sevlet 運(yùn)行需要的標(biāo)準(zhǔn)類庫(kù)、Interface 等。為了方便,應(yīng)用服務(wù)器往往也會(huì)集成 HTTP Server 的功能,但是不如專業(yè)的 HTTP Server 那么強(qiáng)大,所以應(yīng)用服務(wù)器往往是運(yùn)行在 HTTP Server 的背后,執(zhí)行應(yīng)用,將動(dòng)態(tài)的內(nèi)容轉(zhuǎn)化為靜態(tài)的內(nèi)容之后,通過(guò) HTTP Server 分發(fā)到客戶端。
作者:Leh
鏈接:https://www.zhihu.com/question/32212996/answer/55169095
來(lái)源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處

  • 5.1,安裝nginx

    sudo apt-get install nginx
    

    nginx的配置文件在 /etc/nginx/sites-available/里,默認(rèn)的是default文件,如果沒(méi)有,則創(chuàng)建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,啟動(dòng)nginx或重啟nginx (restart)

    service nginx start
    

關(guān)于nginx的詳細(xì)配置可參考如下:
http://www.lxweimin.com/p/fd25a9c008a0
http://www.lxweimin.com/p/3e2b9964c279

第六步:supervisor進(jìn)程守護(hù)

嚴(yán)重推薦這篇介紹 :使用 supervisor 管理進(jìn)程

Supervisor (http://supervisord.org) 是一個(gè)用 Python 寫(xiě)的進(jìn)程管理工具,可以很方便的用來(lái)啟動(dòng)、重啟、關(guān)閉進(jìn)程(不僅僅是 Python 進(jìn)程)。
除了對(duì)單個(gè)進(jìn)程的控制,還可以同時(shí)啟動(dòng)、關(guān)閉多個(gè)進(jìn)程,比如很不幸的服務(wù)器出問(wèn)題導(dǎo)致所有應(yīng)用程序都被殺死,此時(shí)可以用 supervisor 同時(shí)啟動(dòng)所有應(yīng)用程序而不是一個(gè)一個(gè)地敲命令啟動(dòng)。

  • 6.1,安裝supervisor(不在虛擬環(huán)境里)

    pip install supervisor   或者使用  sudo apt-get install supervisor
    
  • 6.2,配置文件 supervisor.conf

用以下命令可以把默認(rèn)的配置生成到制定位置

  echo_supervisord_conf > /your_file_path/supervisord.conf 

如果是使用apt-get安裝的,那么 這個(gè)supervisord.conf文件會(huì)在 /etc/supervisor/文件夾下自動(dòng)生成

; 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

配置文件最后一行,設(shè)置的是要運(yùn)行的進(jìn)程的配置文件路徑,可見(jiàn)只要后綴名是conf即可被識(shí)別,于是新建文件/etc/supervisor/conf.d/webapi.conf

[program:webtest]
directory = /home/bigdata/Project_2017/webapi/ ; 程序的啟動(dòng)目錄
command =/home/bigdata/anaconda2/bin/gunicorn -k gevent -t 300 run:app  ; 啟動(dòng)命令,可以看出與手動(dòng)在命令行啟動(dòng)的命令是一樣的
autostart = true     ; 在 supervisord 啟動(dòng)的時(shí)候也自動(dòng)啟動(dòng)
startsecs = 5        ; 啟動(dòng) 5 秒后沒(méi)有異常退出,就當(dāng)作已經(jīng)正常啟動(dòng)了
autorestart = true   ; 程序異常退出后自動(dòng)重啟
startretries = 3     ; 啟動(dòng)失敗自動(dòng)重試次數(shù),默認(rèn)是 3
user = root          ; 用哪個(gè)用戶啟動(dòng)
redirect_stderr = true  ; 把 stderr 重定向到 stdout,默認(rèn) false
stdout_logfile_maxbytes = 20MB  ; stdout 日志文件大小,默認(rèn) 50MB
stdout_logfile_backups = 20     ; stdout 日志文件備份數(shù)
; stdout 日志文件,需要注意當(dāng)指定目錄不存在時(shí)無(wú)法正常啟動(dòng),所以需要手動(dòng)創(chuàng)建目錄(supervisord 會(huì)自動(dòng)創(chuàng)建日志文件)
stdout_logfile = /home/bigdata/tmp/usercenter_stdout.log

; 可以通過(guò) environment 來(lái)添加需要的環(huán)境變量,一種常見(jiàn)的用法是修改 PYTHONPATH
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

自行修改以上配置

  • 6.3,設(shè)置并啟動(dòng)supervisord(服務(wù)端)

首先,supervisord運(yùn)行是需要有配置文件的,啟動(dòng)supervisord可以直接命令行運(yùn)行

  supervisord

這時(shí),supervisor會(huì)默認(rèn)依次在這幾個(gè)路徑下尋找配置文件

  $CWD/supervisord.conf, 
  $CWD/etc/supervisord.conf, 
  /etc/supervisord.conf

如果這幾個(gè)路徑下沒(méi)有該配置文件,則啟動(dòng)失敗。
所以如果配置文件在其他位置例如/your_file_path/supervisord.conf ,則需要用 -c 設(shè)置

  supervisord -c /your_file_path/supervisord.conf
  • 6.4,啟動(dòng)supervisorctl(客戶端)

命令

  sudo supervisorctl -c /your_file_path/supervisord.conf

這里客戶端和服務(wù)端要使用同一個(gè)supervisord.conf文件,要確保兩者使用的是同一個(gè)!要么都默認(rèn)位置,要么都指定同一位置。
這樣就可以進(jìn)入supervisor客戶端

Supervisor客戶端

這里的web應(yīng)用是對(duì)應(yīng)的/etc/supervisor/conf.d/webapi.conf文件里的配置的,我的配置文件有兩個(gè)即
webapp 和 webtest

這樣,web接口進(jìn)程就被supervisor守護(hù)了,關(guān)掉終端也無(wú)所謂了。

如果要關(guān)閉應(yīng)用進(jìn)程,則進(jìn)入supervisorctl
里面有stop;start;restart等命令,后跟web應(yīng)用名即可

參考文獻(xiàn):

https://zhuanlan.zhihu.com/p/21262280
http://www.lxweimin.com/p/be9dd421fb8d
https://gist.github.com/binderclip/f6b6f5ed4d71fa64c7c5
http://www.cnblogs.com/Ray-liang/p/4837850.html
http://liyangliang.me/posts/2015/06/using-supervisor/
https://www.zhihu.com/question/32212996

PS:錯(cuò)誤之處還請(qǐng)指正,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,540評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,028評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,801評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,223評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,442評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,800評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,996評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,233評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,662評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,926評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,702評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容