python web 部署:nginx + gunicorn + supervisor + flask mac 平臺

前言

之前知乎上面看到蕭大說的Flask學習入門,推薦了一本書叫做《Flask web 開發》。書確實是好書,一口氣讀完簡直是酣暢淋漓,基本上讓我這個Web新人算是入門了。
唯一的問題是,網站開發完成以后,部署成了問題,因為書中部署的章節推薦了Heroku,但是按照書中的一步一步走到17.4.1.4 配置數據庫的時候,各種報錯,google也解決不了。于是決定采用自力更生的方式來部署:

nginx + gunicorn + supervisor + flask

好的教程是入門的開始

找了好多教程,都不太靠譜,后來終于皇天不負有心人,找到了一個比較靠譜的教程,按照教程一步一步操作,全部執行正確(除了有個命令里面寫錯了)
教程地址

python web 部署

web開發中,各種語言爭奇斗艷,web的部署方面,卻沒有太多的方式。簡單而已,大概都是 nginx 做前端代理,中間 webservice 調用程序腳本。大概方式:nginx + webservice + script

nginx 不用多說,一個高性能的web服務器。通常用來在前端做反向代理服務器。所謂正向與反向(reverse),只是英文說法翻譯。代理服務,簡而言之,一個請求經過代理服務器從局域網發出,然后到達互聯網上服務器,這個過程的代理為正向代理。如果一個請求,從互聯網過來,先進入代理服務器,再由代理服務器轉發給局域網的目標服務器,這個時候,代理服務器為反向代理(相對正向而言)。

正向代理:{ 客戶端 ---》 代理服務器 } ---》 服務器
反向代理:客戶端 ---》 { 代理服務器 ---》 服務器 }
{} 表示局域網

nginx既可以做正向,也可以做反向。webservice 的方式同樣也有很多方式。常見的有FastCGIWSGI等。我們采用gunicorn為 wsgi容器。python為服務器script,采用flask框架。同時采用supervisor管理服務器進程。也就是最終的部署方式為:nginx + gunicorn + flask ++ supervisor

創建一個項目

mkdir myproject

創建 python 虛擬環境

virtualenv 可以說是 python 的一個大殺器。用來在一個系統中創建不同的 python 隔離環境。相互之間還不會影響,使用簡單到令人發指。(我的工作路徑是/Users/bayao/code_base/hack/web/flask

mkdir myprojectcd myprojectvirtualenv venv

創建了 venv 環境之后,激活就可以了

source venv/bin/activate

安裝 python web 框架 ---flask

flask 是一個 python web micro framework。簡潔高效,使用也很簡單。flask 依賴兩個庫werkzeugjinjia2。采用 pip 方式安裝即可。

pip install flask

測試我們的 flask 安裝是否成功,并使用 flask 寫一個簡單的 web 服務。vim myapp.py

from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return 'hello world'
if __name__ == '__main__':
    app.debug = True
    app.run()

啟動 flask

python myapp.py

此時,用瀏覽器訪問 http://127.0.0.1:5000 就能看到網頁顯示hello world

使用 gunicorn 部署 python web

現在我們使用 flask 自帶的服務器,完成了 web 服務的啟動。生產環境下,flask 自帶的 服務器,無法滿足性能要求。我們這里采用 gunicorn 做 wsgi容器,用來部署 python。

安裝 gunicorn

pip install gunicorn

pip 是一個重要的工具,python 用來管理包。還有一個最佳生產就是每次使用 pip 安裝的庫,都寫入一個 requirement 文件里面,既能知道自己安裝了什么庫,也方便別人部署時,安裝相應的庫。

pip freeze > requirements.txt

以后每次 pip 安裝了新的庫的時候,都需freeze 一次。

當我們安裝好 gunicorn 之后,需要用 gunicorn 啟動 flask,注意 flask 里面的name里面的代碼啟動了 app.run(),這個含義是用 flask 自帶的服務器啟動 app。這里我們使用了 gunicorn,myapp.py 就等同于一個庫文件,被 gunicorn 調用。

gunicron -w4 -b0.0.0.0:5000 myapp:app

其實gunicron就是替代Flask自帶的一個web server,啟動命令其實超級簡單

其中 gunicorn 的部署中,-w 表示開啟多少個 worker,-b 表示 gunicorn 開發的訪問地址。
想要結束 gunicorn 只需執行 pkill gunicorn,有時候還要用 ps 找到 pid 進程號才能 kill。可是這對于一個開發來說,太過于繁瑣,因此出現了另外一個神器---supervisor
,一個專門用來管理進程的工具,還可以管理系統的工具進程。


安裝 supervisor

pip install supervisor
echo_supervisord_conf > supervisor.conf           # 生成 supervisor 默認配置文件
vim supervisor.conf                               # 修改 supervisor 配置文件,添加 gunicorn 進程管理

在myapp supervisor.conf 配置文件底部添加 (注意我的工作路徑是/home/rsj217/rsj217/)

[program:myapp]
command=/home/rsj217/rsj217/myproject/venv/bin/gunicorn -w4 -b0.0.0.0:2170 myapp:app    ; supervisor啟動命令
directory=/home/rsj217/rsj217/myproject                                                 ; 項目的文件夾路徑
startsecs=0                                                                             ; 啟動時間
stopwaitsecs=0                                                                          ; 終止等待時間
autostart=false                                                                         ; 是否自動啟動
autorestart=false                                                                       ; 是否自動重啟
stdout_logfile=/home/rsj217/rsj217/myproject/log/gunicorn.log                           ; log 日志
stderr_logfile=/home/rsj217/rsj217/myproject/log/gunicorn.err                           ; 錯誤日志

supervisor的基本使用命令

supervisord -c supervisor.conf                             通過配置文件啟動supervisor
supervisorctl -c supervisor.conf status                    察看supervisor的狀態
supervisorctl -c supervisor.conf reload                    重新載入 配置文件
supervisorctl -c supervisor.conf start [all]|[appname]     啟動指定/所有 supervisor管理的程序進程
supervisorctl -c supervisor.conf stop [all]|[appname]      關閉指定/所有 supervisor管理的程序進程

supervisor 還有一個web的管理界面,可以激活。更改下配置

[inet_http_server]         ; inet (TCP) server disabled by default
port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
username=user              ; (default is no username (open server))
password=123               ; (default is no password (open server))

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
username=user              ; should be same as http_username if set
password=123                ; should be same as http_password if set
;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history  ; use readline history if available

現在可以使用 supervsior 啟動 gunicorn啦。運行命令supervisord -c supervisor.conf
訪問 http://127.0.0.1:9001 可以得到 supervisor的web管理界面,訪問 http://127.0.0.1:2170 可以看見gunciron 啟動的返回的 hello world

安裝配置 nginx

采用 apt-get方式安裝最簡單。運行sudo apt-get install nginx。安裝好的nginx的二進制文件放在/usr/sbin/文件夾下面。而nginx的配置文件放在/etc/nginx下面。

使用 supervisor 來管理 nginx。這里需要注意一個問題,linux的權限問題。nginx是sudo的方式安裝,啟動的適合也是 root用戶,那么我們現在也需要用 root用戶啟動supervisor。增加下面的配置文件

[program:nginx]
command=/usr/sbin/nginx
startsecs=0
stopwaitsecs=0
autostart=false
autorestart=false
stdout_logfile=/home/rsj217/rsj217/myproject/log/nginx.log
stderr_logfile=/home/rsj217/rsj217/myproject/log/nginx.err

到此為止,進步的 web 部屬已經完成。當然,最終我們需要把項目代碼部屬到服務器上.批量的自動化部屬需要另外一個神器 fabric.具體使用,就不再這篇筆記闡述。項目源碼中包含了fabric文件。下載fabric,更改里面的用戶名和秘密,就可以部屬在自己或者遠程的服務器上了。

項目源碼: https://coding.net/u/rsj217/p/myproject/git

針對自己MAC上的調整

因為上面的教程給出的是linux下面的命令,我在自己MAC上實際測試稍微有點變化

  • 啟動Flask web程序的時候,實際是通過manage.py來啟動,所以gunicorn后面的參數改成如下:
gunicorn -w4 -b0.0.0.0:5000 manage:app
  • 在mac上安裝nginx,最簡單的方法是先安裝brew,然后
brew install nginx
  • 通過find / -name 'nginx'找到了系統里面的所有nginx,然后一個一個驗證,發現準確的路徑如下:
/usr/local/etc/nginx/nginx.conf              #nginx 的配置文件                 
/usr/local/Cellar/nginx/1.10.1/bin/nginx     #啟動nginx的路徑

nginx 相關命令:菜鳥網

nginx -t  #檢查配置文件ngnix.conf的正確性命令
nginx -s reload # 重新載入配置文件
nginx -s reopen # 重啟 Nginx
nginx -s stop # 停止 Nginx
  • 8080端口被占用的情況
    啟動nginx的時候發現8080端口被占用,在stack overflow上找到了解決方法
    8080端口被占用問題

  • 通過瀏覽器,查看nginx


    截圖

配置nginx

nginx 部署

server {
    listen 1024;     #表示訪問nginx服務器的地址是127.0.0:1024
    server_name example.org; # 這是HOST機器的外部域名,用地址也行

    location / {
        proxy_pass http://127.0.0.1:5000; # 這里是指向 gunicorn host 的服務地址
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

  }

總結一下就是
-寫好Flask web程序,運行在自帶的web server上
-運行在生產環境的服務器上,例如gunicorn 上
-外面套一層ngnix服務器,好處如下
有了gunicorn,為何還需要nginx

遇到的問題:nginx服務器,不能處理post信息,get能拿到,一post就死了。
后面還要學習:
epoll,gevent,greenlet

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

推薦閱讀更多精彩內容