flask+uwsgi+supervisor+nginx在局域網服務器上部署實踐

flask能夠快速的搭建http服務,可是爲了搭建網站仍是須要web服務器和相關監控管理操做,一套flask、uwsgi、supervisor、nginx是較好的完整解決方案。html

本文對本身學習作一個記錄,以一個簡單的顯示‘Hello Flask!’程序來測試,跑通整個流程,方式是在局域網服務器上部署,在我的電腦上訪問。python

服務器系統是centos7 安裝了pyenv pyenv 切換到python3.5版本,不懂版本切換的能夠參考我這邊文章https://www.jianshu.com/p/492853d0e683nginx

新建一個簡單程序test_flask.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello Flask!'

if __name__ == '__main__':
    app.run(host='0.0.0.0',port=8080)

測試局域網訪問

在服務器上運行# python test_flask.py,出現以下: flask 此時,在我的電腦瀏覽器輸入10.12.28.27:8080,(10.12.28.27是我服務器ip),出現以下錯誤: 鏈接不上 ok,此時緣由多是服務器防火牆打開了,須要關閉,在服務器上輸入關閉防火牆命令(注意系統不一樣命令也不一樣): centos7關閉防火牆 關閉後,在我的電腦瀏覽器輸入10.12.28.27:8080,出現hello,Flask!(注意web進程必定要設置ip:0.0.0.0,公網才能訪問到) 訪問成功返回 ##搭建uWSGI服務 Flask 是一個 Web 應用框架,框架的做用在於處理 request 和 reponse,使用的是 Python 自帶的 simple HTTPServer 建立的,在安全性和效率上都是不行的,而uWSGI 是一個全功能的 HTTP 服務器,他要作的就是把 HTTP 協議轉化成語言支持的網絡協議。好比把 HTTP 協議轉化成 WSGI 協議,讓 Python 能夠直接使用。 uwsgi 是一種 uWSGI 的內部協議,使用二進制方式和其餘應用程序進行通訊。 如今,咱們結束上面的flask服務,在服務器上安裝uWSGI,直接輸入以下命令web

pip install uwsgiflask

安裝完,直接輸入啓動命令:centos

uwsgi --http 0.0.0.0:8080 --home env --wsgi-file test_flask.py --callable app --master瀏覽器

出現以下錯誤緩存

Fatal Python error: Py_Initialize: Unable to get the locale encoding ImportError: No module named 'encodings'安全

緣由是--home參數,之前uwsgi須要這個參數來指定python環境變量的目錄,如今不須要這個參數,直接:服務器

uwsgi --http 0.0.0.0:8080 --wsgi-file test_flask.py --callable app --master

運行成功: uwsgi 在我的電腦瀏覽器輸入10.12.28.27:8080,出現Hello,Flask!(注意uwsgi配置ip:0.0.0.0,公網才能訪問到) 固然,爲了減小輸入命令麻煩,能夠用配置文件來啓動uwsgi, 在當前目錄新建 vi uwsgi_config.ini:

[uwsgi]
# uwsgi 啓動時所使用的地址與端口
# socket = 0.0.0.0:8080 
# 外網訪問端口,若是直接用uWSGI外網,這裏因爲使用了Nginx,故註釋掉
http= 0.0.0.0:8080
# 指向項目地址
chdir = /root/zlw/web_flask/
# python 啓動程序文件,應該在上面的目錄中
wsgi-file = test_flask.py 
# python 程序內用以啓動的 application 變量名
# app 是 manage.py 程序文件內的一個變量,這個變量的類型是 Flask的 application 類
callable = app 
# 處理器數
processes = 4
# 線程數
threads = 2
#狀態檢測地址
stats = 127.0.0.1:9191

配置文件啓動uwsgi(這裏uwsgi_config.ini是在當前目錄下):

uwsgi uwsgi_config.ini

ok,此時,你的應用已經得到了高併發的處理能力,但對於靜態文件的處理uwsgi比較笨拙,而且這種方式安全性也不高,因此要加上Nginx反向代理服務。

在增長Nginx服務以前,咱們還有一個事情要作,考慮一下:我如今有一個進程須要每時每刻不斷的跑,可是這個進程又有可能因爲各類緣由有可能中斷。當進程中斷的時候我但願能自動從新啓動它,此時,我就須要使用到了Supervisor,supervisor管理進程,是經過fork/exec的方式將這些被管理的進程看成supervisor的子進程來啓動,因此咱們只須要將要管理進程的可執行文件的路徑添加到supervisor的配置文件中就行了。此時被管理進程被視爲supervisor的子進程,若該子進程異常中斷,則父進程能夠準確的獲取子進程異常中斷的信息,經過在配置文件中設置autostart=ture,能夠實現對異常中斷的子進程的自動重啓。

搭建supervisor進程管理

沒有supervisor以前啓動uwsgi服務是這樣:uwsgi uwsgi_config.ini 如今我準備使用Supervisor,故uwsgi啓動命令僅供測試的時候用。 安裝supervisor:

yum install supervisor

打開全局配置文件(先找到配置文件路徑:find / -name supervisord.conf)

vi /etc/supervisord.conf

在末尾加入:

[program:Test-flask]
# 啓動命令入口
command=uwsgi /root/zlw/web_flask/uwsgi_config.ini

# 命令程序所在目錄
directory=/root/zlw/web_flask
#運行命令的用戶名
user=root

autostart=true   # supervisor啓動的時候是否隨着同時啓動
autorestart=true  # 當程序跑出exit的時候,這個program會自動重啓
startsecs=3   # 程序重啓時候停留在runing狀態的秒數
#日誌地址
stdout_logfile=/root/zlw/web_flask/uwsgi_supervisor.log

supervisor 相關操做:

啓動:supervisord 打開命令行: supervisorctl
命令行中查看命令: help
命令行中查看狀態: status

或者
supervisorctl status //查看狀態
supervisorctl stop [進程名] //中止 supervisorctl start [進程名]

輸入命令supervisord啓動,子程序uwsgi服務將隨之啓動。 這個時候輸入: ps -ef | grep uwsgi 能看到運行的uwsgi程序: uwsgi已經啓動

在我的電腦瀏覽器輸入10.12.28.27:8080,出現Hello,Flask!(注意uwsgi配置ip:0.0.0.0,公網才能訪問到) supervisor搭建完畢。

搭建Nginx服務

從上面的講解中,咱們知道,uWSGI 能夠起到 Web 服務器的做用,那麼爲何有了 uWSGI 還須要 Nginx 呢?

最廣泛的說法是 Nginx 對於處理靜態文件更有優點,性能更好。其實若是是小網站,沒有靜態文件須要處理,只用 uWSGI 也是能夠的,但加上 Nginx 這一層,優點能夠很具體:

  • 對於運維來講比較方便,若是服務器被某個 IP 攻擊,在 Nginx 配置文件黑名單中添加這個 IP 便可,若是隻用 uWSGI,那麼就須要在代碼中修改了。另外一方面,Nginx 是身經百戰的 Web 服務器了,在表現上 uWSGI 顯得更專業,好比說 uWSGI 在早期版本里是不支持 https 的,能夠說 Nginx 更安全。

  • Nginx 的特色是可以作負載均衡和 HTTP 緩存,若是不止一臺服務器,Nginx 基本就是必選項了,經過 Nginx,將資源能夠分配給不一樣的服務器節點,只有一臺服務器,也能很好地提升性能,由於 Nginx 能夠經過 headers 的Expires or E-Tag,gzip 壓縮等方式很好地處理靜態資源,畢竟是 C 語言寫的,調用的是 native 的函數,針對 I/O作了優化,對於動態資源來講,Nginx 還能夠實現緩存的功能,配合 CDN 優化(這是 uWSGI 作不到的)。Nginx 支持epoll/kqueue 等高效網絡庫,可以很好地處理高併發短鏈接請求,性能比 uWSGI 不知道高到哪裏去了。

  • 若是服務器主機上運行了PHP,Python 等語言寫的多個應用,都須要監聽80端口,這時候 Nginx 就是必選項了。由於咱們須要一個轉發的服務。 安裝:

yum install nginx

打開全局配置文件(先找到配置文件路徑:find / -name nginx.conf)

vi /etc/nginx/nginx.conf

修改配置:(注意先備份一份)

server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  10.12.28.27;  # 這裏是服務域名,請求的url必須包含該字段Nginx才能響應。
        #root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        # include /etc/nginx/default.d/*.conf;

        access_log /root/zlw/web_flask/nginx_access.log;  # 服務器接收的請求日誌
        error_log /root/zlw/web_flask/nginx_error.log;  # 錯誤日誌
        location / {
            include  uwsgi_params;
            uwsgi_pass 0.0.0.0:8080;  # 指向uwsgi 所應用的內部地址,全部請求將轉發給uwsgi 處理
            uwsgi_param UWSGI_CHDIR  /root/zlw/web_flask; # 指向網站根目錄
            uwsgi_param UWSGI_SCRIPT test_flask:app;  # 指定啓動程序

nginx一些操做:

驗證配置是否正確:nginx -t 啓動: nginx 重啓: nginx -s reload 中止: nginx -s quit

啓動後,在我的電腦瀏覽器輸入10.12.28.27:80,出現很卡的想象,一直出不來結果,等很久提示以下: nginx配置錯誤

分析緣由:配置出現問題。 從新設置配置,將默認配置/etc/nginx/nignx.conf還原爲原來的配置。而且默配置文件內有以下配置

include /etc/nginx/conf.d/*.conf;

ok,新建一個配置:

vi /etc/nginx/conf.d/my_nginx.conf

輸入以下內容:

server {
    listen      80;
    server_name  10.12.28.27;  # 服務器ip,
    charset    utf-8;

    client_max_body_size 100M;

    location / {
        include uwsgi_params;
        #uwsgi_pass  unix:/root/zlw/web_flask/flask_uwsgi.sock;  # sock方式跑不通,緣由未知
        uwsgi_pass 127.0.0.1:8080;
    }
}

同時,修改以前的uwsgi_config.ini配置文件(注意本身的文件路徑):

vi /root/zlw/web_flask/uwsgi_config.ini
修改成:

[uwsgi]

# uwsgi 啓動時所使用的地址與端口
 socket = 127.0.0.1:8080
#socket = /root/zlw/web_flask/flask_uwsgi.sock  # 經過sock文件的方式行不通,緣由未知

#permissions for the socket file
#chmod-socket    = 666


# 外網訪問端口,若是直接用uWSGI外網,這裏因爲使用了Nginx,故註釋掉
#http= 127.0.0.1:8080

# 指向項目地址
chdir = /root/zlw/web_flask/

# python 啓動程序文件
wsgi-file = test_flask.py

# python 程序內用以啓動的 application 變量名
# app 是 manage.py 程序文件內的一個變量,這個變量的類型是 Flask的 application 類
callable = app

# 處理器數
processes = 1

# 線程數
threads = 2

#狀態檢測地址
stats = 127.0.0.1:9191

保存好,重啓supervisor,重啓nginx

在我的電腦瀏覽器輸入10.12.28.27:80,出現Hello,Flask! 輸入10.12.28.27:8080將出現沒法訪問狀況。由於uwsgi 服務ip設置爲127.0.0.1了,其餘電腦沒法訪問,只能經過nginx的監聽端口80進行訪問。若uwsgi 服務指定ip:0.0.0.0:8080,則,其餘電腦輸入10.12.28.27:8080也能從新hello,flask,固然10.12.28.27:80也能(uwsgi配置ip要和nginx配置一致)

到此能跑通也算大功告成了,可是不能知足,當咱們服務器運行了多個flask時該怎麼處理呢,下面咱們就繼續嘗試管理多個進程時的相關配置操做。


##啓動多個Flask進程 咱們分別創建兩個測試項目:

  • /root/web_flask
  • /root/zlw

每一個項目目錄下分別有文件:

  • test_flask1.py,uwsgi_config1.ini,logs/
  • test_flask2.py,uwsgi_config2.ini,logs/

test_flask1.py 和test_flask2.py是和上面簡單測試程序同樣的,uwsgi配置啓動端口和檢測端口分別不同。

uwsgi配置 uwsgi_config1.ini:

[uwsgi]
# uwsgi 啓動時所使用的地址與端口
 socket = 127.0.0.1:8080 
# 指向項目地址
chdir = /root/web_flask/
# python 啓動程序文件
wsgi-file = test_flask1.py
# python 程序內用以啓動的 application 變量名
# app 是 manage.py 程序文件內的一個變量,這個變量的類型是 Flask的 application 類
callable = app 
# 處理器數
processes = 1
# 線程數
threads = 2
#狀態檢測地址
stats = 127.0.0.1:9191

uwsgi_config2.ini:

[uwsgi]
# uwsgi 啓動時所使用的地址與端口
 socket = 127.0.0.1:7070 
# 指向項目地址
chdir = /root/zlw/
# python 啓動程序文件
wsgi-file = test_flask2.py
# python 程序內用以啓動的 application 變量名
# app 是 manage.py 程序文件內的一個變量,這個變量的類型是 Flask的 application 類
callable = app 
# 處理器數
processes = 1
# 線程數
threads = 2
#狀態檢測地址
stats = 127.0.0.1:7171

此時測試一下,uwsgi分別啓動項目(注意只能單個分別啓動,ctrl+c結束) uwsgi /root/web_flask/uwsgi_config1.ini uwsgi /root/zlw/uwsgi_config2.ini 分別都能啓動成功,進行supervisor配置,經過supervisor來同時啓動兩個項目。

supervisor配置 個人supervisor默認配置是/etc/supervisor.conf,打開會找到相似這樣的配置

[include] files = supervisord.d/*.ini

所以能夠在/etc/supervisord.d/目錄下的構建兩個進程的配置文件.ini各式。固然也能夠直接在默認配置文件中增長進程配置。 如下是個人配置(增長兩個進程配置文件,同時記得將默認配置文件原來設置的進程配置刪除掉): /etc/supervisord.d/my_flask1.ini

[program:Test-Flask1]
command=uwsgi /root/web_flask/uwsgi_config1.ini
stdout_logfile=/root/web_flask/logs/supervisor.log
autostart=true
autorestart=true
startsecs=5  # 啓動5秒內沒異常說明啓動成功。
priority=1  # 啓動優先級
stopasgroup=true  # 程序被終止是否通知用戶組
killasgroup=true  #被kill是否通知用戶組

/etc/supervisord.d/my_flask2.ini

[program:Test-Flask2]
command=uwsgi /root/zlw/uwsgi_config2.ini
stdout_logfile=/root/zlw/logs/supervisor.log
autostart=true
autorestart=true
startsecs=5  # 啓動5秒內沒異常說明啓動成功。
priority=1  # 啓動優先級
stopasgroup=true  # 程序被終止是否通知用戶組
killasgroup=true  #被kill是否通知用戶組

啓動supervisord,打開supervisorctl能看到啓動成功。 兩個進程啓動成功 此時,已經能夠在服務器電腦上分別訪問127.0.0.1:8080和127.0.0.1:7070,都將返回Hello Flask。

配置Nginx 分別爲每一個進程配置一個nginx配置文件,文件目錄/etc/nginx/conf.d/ 有以下文件: web_flask1.conf:(監聽80端口指向127.0.0.1:8080)

server {
    listen      80;
    server_name  10.12.28.27;
    charset    utf-8;
 
    client_max_body_size 100M;

    access_log /root/web_flask1/logs/nginx_access.log;  # 服務器接收的請求日誌
    error_log /root/web_flask1/logs/nginx_error.log;  # 錯誤日誌
 
    location / {
        include uwsgi_params;
        #uwsgi_pass  unix:/root/web_flask/flask_uwsgi.sock;
        uwsgi_pass 127.0.0.1:8080;
    }
}

web_flask2.conf:(監聽70端口指向127.0.0.1:7070)

server {
    listen      70;
    server_name  10.12.28.27;
    charset    utf-8;
 
    client_max_body_size 100M;

    access_log /root/web_flask2/logs/nginx_access.log;  # 服務器接收的請求日誌
    error_log /root/web_flask2/logs/nginx_error.log;  # 錯誤日誌
 
    location / {
        include uwsgi_params;
        #uwsgi_pass  unix:/root/web_flask/flask_uwsgi.sock;
        uwsgi_pass 127.0.0.1:7070;
    }
}

好了,配置結束。重啓nginx

在我的電腦瀏覽器輸入10.12.28.27:80,出現Hello,Flask! 在我的電腦瀏覽器輸入10.12.28.27:70,出現Hello,Flask!

相關文章
相關標籤/搜索