Ubuntu配置環(huán)境3:Nginx+Gunicorn+Supervisor

首先,本文的mysite是指自己的站點名稱。

安裝nginx

 apt-get install nginx

關閉nginx默認的log

vi /etc/nginx/nginx.conf
找到以下access_log和error_log,修改為null。
access_log /dev/null;
error_log /dev/null;

接下來配置站點配置,進入nginx站點配置目錄,并新建配置文件

cd /etc/nginx/sites-available/
vi mysite

寫入一下對應站點配置文本,并保存

server {  
        listen   80;  
        server_name www.mysite.com mysite.com;
        #修改最大上傳為10M,默認為2M,超出大小出現(xiàn)413 Request Entity Too Large錯誤
        client_max_body_size 10M;
         #一定要記得在網(wǎng)站目錄下創(chuàng)建logs文件夾,不然會報錯,不需要可注釋掉
        #access_log /var/www/mysite/logs/access.log;
        #error_log /var/www/mysite/logs/access.log;
        

        #默認請求,nginx反向代理(動態(tài)頁面轉發(fā)至gunicorn)
        location / {  
            #將訪客IP加入headers中,否則獲取到的將是127.0.0.1
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;  
            proxy_redirect off;  
            #如果請求的文件不存在,則將路由轉發(fā)到gunicorn的8000端口
            if (!-f $request_filename) {  
                proxy_pass http://127.0.0.1:8000;  
                break;  
            }  
        }

        #靜態(tài)文件請求轉發(fā)給目錄
        location ^~ /static/ {
                root /var/www/mysite/app;
        }
    }

上面的內容中proxy_pass http://127.0.0.1:8000; 是表示動態(tài)頁面轉發(fā)到本機8000端口,這個端口就是gunicorn開放的服務。
這樣靜態(tài)頁面nginx就直接返回給訪客,動態(tài)頁面則轉發(fā)給gunicorn處理。

這里插一句:由于使用nginx反向代理到gunicorn,那么在flask中獲取IP就需要

//X-Forward-For參數(shù)為nginx反向代理轉發(fā)到gunicorn時設置的參數(shù)
ip = request.headers.get('X-Forward-For') or request.remote_addr

啟用站點配置文件

cd /etc/nginx/sites-enabled
#添加引用鏈接
ln -s /etc/nginx/sites-available/mysite ./mysite
#查看引用是否成功
ls -l
Paste_Image.png

檢測配置文件是否有錯誤

sudo nginx -t

重啟nginx

service nginx restart

開啟防火墻端口

如果系統(tǒng)中沒有安裝ufw,則可以跳過,沒有安裝的話表現(xiàn)為命令不識別。
安裝了ufw的話,如果相關端口沒有開放,配置好nginx后會出現(xiàn)自己可以訪問(wget網(wǎng)址試試),外網(wǎng)卻無法訪問

#查看開放的端口
ufw status
#添加80端口
ufw allow 80
Paste_Image.png

安裝Gunicorn

進入配置好的virtualenvs虛擬目錄,激活網(wǎng)站虛擬環(huán)境

cd /var/virtualenvs
source mysite_venv/bin/activate

安裝Gunicorn

pip install gunicorn
#進入網(wǎng)站根目錄
cd /var/www/mysite
#創(chuàng)建配置文件
vi gunicorn.conf

輸入配置文本并保存:

# 進程為5
workers = 5

# 監(jiān)聽本地8000端口,之后這個端口來的就是看這個網(wǎng)站的。
bind = '127.0.0.1:8000'

#如果要搭配gevent使用,請加上取消注釋
#worker_class="gevent" #sync, gevent,meinheld

注意:如果需要使用gevent模式,請先pip install gevent,然后在gunicorn.conf配置文件中加上worker_class="gevent",其他都和往常一樣。

gunicorn啟動測試

cd /var/www/mysite
gunicorn -c gunicorn.conf myapp:app

啟動后提示:


Paste_Image.png

到這里gunicorn已經(jīng)安裝并配置好了,如果要正常用gunicorn啟動網(wǎng)站項目,需要項目中有對應的啟動文件,現(xiàn)在可以先跳過這一步,直接跳到安裝Supervisor。

當我們安裝并配置好 gunicorn 之后,需要用 gunicorn 啟動 flask,注意網(wǎng)站項目中 manage.py里面的 app.run(),這句代碼是作為 flask 自帶的server服務的啟動 入口,由于flask自帶的server很性能很差,這里我們服務器上使用 gunicorn,manage.py和myapp.py一樣,都是作為啟動入口文件,供server調用運行。在項目的manage.py文件中,gunicom不會執(zhí)行代碼中的.run(),是需要加上一段代碼對接gunicom。

在網(wǎng)站項目中需要一個gunicorn的啟動入口的文件,如果沒有就自己新建一個文件,名字無所謂,我取的是myapp.py,
內容為

import os
from app import create_app,db

app = create_app(os.getenv('mysite_CONFIG') or 'default')

#使用Gunicorn需要這兩行代碼對接
from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

這個文件和manage.py一樣,也是一個啟動文件,不同的是,myapp.py專門作為gunicorn啟動使用,manage.py是用作flask自帶的web-server啟動,同時manage.py里面還有一些管理代碼,一樣可以使用python manage.py shell或python manage.py db init等命令來管理數(shù)據(jù)庫。

運行Gunicorn,
--config gunicorn.conf是根據(jù)配置文件來運行
manage為自己的run文件

gunicorn -c gunicorn.conf myapp:app

安裝Supervisor

我們的網(wǎng)站現(xiàn)在雖然能訪問了,但是假如你重啟服務器,網(wǎng)站的動態(tài)文件就會打不開,因為gunicorn不會開機自己啟動,需要一個小保姆開機后自動給他啟動,這里我們就使用supervisor。

Supervisor是一款服務器管理工具,用于監(jiān)控和守護進程。阿里云會偶爾宕機,宕機后會切換物理服務,造成服務器重啟。故而官網(wǎng)也強調過,程序最好有自動重啟、重連機制。所以我們需要Supervisor當保姆,照顧我們的后臺進程。

 apt-get install supervisor

注意:supervisor需要系統(tǒng)默認是python2.7才能兼容支持,否則會安裝失敗,使用python -V查看系統(tǒng)默認py版本

向supervisor添加gunicorn的啟動項

cd /etc/supervisor/conf.d
vi mysite.conf

粘貼一下文本并保存

# 進程的名字,取一個以后自己一眼知道是什么的名字。(這行字不能刪,第一行需要一行注釋,刪了就有問題)
[program:mysite]
# 定義Gunicorn啟動命令,我們手動在ssh啟動Gunicorn需要cd到網(wǎng)站目錄然后輸入 gunicorn -c gunicorn.conf myapp:app,所以這里所有路徑都要寫成絕對路徑,這樣系統(tǒng)才能找到這些路徑
command=/var/virtualenvs/mysite_venv/bin/gunicorn myapp:app -c /var/www/mysite/gunicorn.conf
# 網(wǎng)站目錄
directory=/var/www/mysite
# 進程所屬用戶
user=root
# 自動重啟設置。
autostart=true
autorestart=true
# 日志存放位置(可能造成print中文UnicodeEncodeError)
#stdout_logfile=/var/www/mysite/logs/gunicorn_supervisor.log
# 設置環(huán)境變量。這里這行的意思是:設置環(huán)境變量MODE的值為UAT。請根據(jù)自己的需要配置,如沒有需要這行可以刪除。
#environment = MODE="UAT"

[supervisord]

保存后就進入supervisorctl控制臺

supervisorctl

進入控制臺

reread
update
start mysite

啟動完成后,以后每次開機supervisor都會幫我們自動按照配置文件啟動gunicorn服務。

Paste_Image.png

如果發(fā)生錯誤請退出控制臺,嘗試重啟服務

service supervisor restart

現(xiàn)在重啟服務器后,如果網(wǎng)站能正常訪問了,說明gunicorn自動啟動了,這也表示我們的supervisor配置成功了。

以后如果更新了網(wǎng)站項目文件,讓gunicorn重新加載新的項目文件也只需要使用supervisor管理gunicorn進程就好了。
重新載入配置文件并停止所有進程并按新的配置啟動:supervisorctl reload

以下是所有supervisorctl 的命令

supervisorctl status: 查看當前運行的進程列表
supervisorctl stop xxx: 停止某一個進程(xxx),xxx為[program:theprogramname]里配置的值。
supervisorctl start xxx: 啟動某個進程
supervisorctl restart xxx: 重啟某個進程
supervisorctl stop groupworker: 重啟所有屬于名為groupworker這個分組的進程(start,restart同理)
supervisorctl stop all,停止全部進程,注:start、restart、stop都不會載入最新的配置文件。
supervisorctl reload,載入最新的配置文件,停止原有進程并按新的配置啟動、管理所有進程。
supervisorctl update,根據(jù)最新的配置文件,啟動新配置或有改動的進程,配置沒有改動的進程不會受影響而重啟。
注意:顯示用stop停止掉的進程,用reload或者update都不會自動重啟。

supervisor使用中遇到的一些錯誤

============錯誤A
參考https://www.v2ex.com/t/210122

如果提示unix:///var/run/supervisor.sock no such file
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 224
這表明supervisord服務端沒有成功啟動,多半是/etc/supervisor/conf.d下面自己的配置文件出問題

cd /etc/supervisor/conf.d
supervisord -c mysite.conf
Paste_Image.png

這里就告訴我配置文件17行出了問題

修改好配置文件后,

#重新生成supervisor.sock文件,啟動監(jiān)聽服務
supervisord -c supervisord.conf
#重新加載自定義配置文件
supervisorctl reload

============錯誤B
如果配置文件有錯誤,會提示你提示

Paste_Image.png

如果有錯誤則exit退出控制臺,vi mysite.conf修改錯誤后再繼續(xù)進入控制臺,并reread重新讀取配置文件。
如果都正確了,則在supervisorctl的控制臺中輸入命令,啟動supervisor任務。
(注意:如果要supervisor啟動任務,則會啟動gunicorn,自己先使用gunicorn命令試試能否正常啟動網(wǎng)站項目)。

#進入網(wǎng)站目錄
cd /var/www/mysite
#測試能否正常啟動網(wǎng)站項目
gunicorn -c gunicorn.conf myapp:app

如果能正常啟動就ctrl+c結束,然后繼續(xù)進入supervisorctl啟動任務。

supervisorctl

==============錯誤C

這樣就錯誤:

[program:taokeapi]
# 定義Gunicorn啟動命令,我們手動在ssh啟動Gunicorn需要cd到網(wǎng)站目錄然后輸入 gunicorn -c gunicorn.conf myapp:app,所以>這里所有路徑都要寫成絕對路徑,這樣系統(tǒng)才能找到這些路徑
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 網(wǎng)站目錄
directory=/var/www/taokeapi
# 進程所屬用戶
user=root
# 自動重啟設置。
autostart=true
autorestart=true

[supervisord]

這樣就正確:

# 進程的名字,取一個以后自己一眼知道是什么的名字。
[program:taokeapi]
# 定義Gunicorn啟動命令,我們手動在ssh啟動Gunicorn需要cd到網(wǎng)站目錄然后輸入 gunicorn -c gunicorn.conf myapp:app,所以>這里所有路徑都要寫成絕對路徑,這樣系統(tǒng)才能找到這些路徑
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 網(wǎng)站目錄
directory=/var/www/taokeapi
# 進程所屬用戶
user=root
# 自動重啟設置。
autostart=true
autorestart=true

[supervisord]

差別僅僅是第一行多了一行注釋。。。
不知道是BUG還是什么,總之第一行需要注釋,去掉就會出問題。。。

======錯誤D

Paste_Image.png

使用supervisor啟動gunicorn,執(zhí)行print就出錯。
而直接啟動gunicorn則沒問題。
可見錯誤在supervisor上面。。

經(jīng)過多次排查,發(fā)現(xiàn),
vi /etc/supervisor/conf.d/taokeapi.conf配置文件中多了一行,

stdout_logfile=/var/www/mysite/logs/gunicorn_supervisor.log

由于supervisor是基于python2,當運行python3的項目時,print就會被寫入這個日志文件,python2在有些系統(tǒng)中輸出中文就會出現(xiàn)UnicodeEncodeError錯誤。
解決辦法:
配置文件中去掉這行輸出日志目錄,完整配置如下:

# 進程的名字,取一個以后自己一眼知道是什么的名字。
[program:taokeapi]
# 定義Gunicorn啟動命令,我們手動在ssh啟動Gunicorn需要cd到網(wǎng)站目錄然后輸入 gunicorn -c gunicorn.conf myapp:app,所以>這里所有路徑都要寫成絕對路徑,這樣系統(tǒng)才能找到這些路徑
command=/var/virtualenvs/taokeapi_venv/bin/gunicorn myapp:app -c /var/www/taokeapi/gunicorn.conf
# 網(wǎng)站目錄
directory=/var/www/taokeapi
# 進程所屬用戶
user=root
# 自動重啟設置。
autostart=true
autorestart=true

[supervisord]

然后重新加載配置文件

supervisord -c taokeapi.conf

supervisorctl
>reread
>update
>reload

這樣就發(fā)現(xiàn)沒問題了

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

推薦閱讀更多精彩內容