CentOS7下python3+Flask+uWSGI+Nginx+Supervisor環境搭建

在生產環境中通常用uwsgi作爲Flask的web服務網關,通過nginx反向代理進行負載均衡,通過supervior進行服務進行的管理。這一套搭下來還是有一些坑要踩,本文通過一個簡單的Flask web應用記錄了CentOS7下python3+Flask+uWSGI+Nginx+Supervisor環境搭建的全過程,以及一些注意事項,以免遺忘。

一、Python3環境安裝

CentOS7下Python3環境安裝參考 http://xiejava.ishareread.com/posts/57cef505/

查看python版本

[root@localhost ~]# python -V
Python 3.8.12

二、安裝Flask

1、創建Python虛擬環境

在home目錄下創建flask_web目錄(目錄根據具體實際環境創建,本教程是/home/flask_web)
通過venv創建虛擬環境
[root@localhost flask_web]# python -m venv /home/flask_web
創建成功後可以看到在目錄下自動建了一些文件夾,包括python命令及依賴庫等,激活以後是個獨立的python虛擬運行環境。
python虛擬運行環境在目錄下運行source bin/activate 激活虛擬環境

[root@localhost flask_web]# source bin/activate
(flask_web) [root@localhost flask_web]# 

2、安裝Flask

通過pip install flask安裝flask

(flask_web) [root@localhost flask_web]# pip install flask

安裝的時候有可能報ModuleNotFoundError: No module named '_ctypes’的錯誤,原因是缺少libffi-devel包,具體可參考 https://blog.csdn.net/qq_36416904/article/details/79316972
安裝Flask報錯

運行yum install libffi-devel -y 並且要重新編譯執行安裝python
解決包依賴的問題
(flask_web) [root@localhost flask_web]# yum install libffi-devel -y
進入到python源碼包目錄 執行使用make&make install 命令重新編譯並安裝python(這裏比較坑)
然後再pip install flask 進行安裝
安裝完成後可以嘗試運行flask run,提示沒有Flask應用程序,說明flask已經安裝成功並且可以運行了。

(flask_web) [root@localhost flask_web]# flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
Usage: flask run [OPTIONS]
Try 'flask run --help' for help.

Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.

3、建立測試應用
vi hello.py創建一個hello.py的文件,copy下面的內容到文件中:wq保存退出

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

通過python hello.py運行測試程序

(flask_web) [root@localhost flask_web]# python hello.py
 * Serving Flask app 'hello' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

新開一個shell窗口執行curl http://127.0.0.1:5000/ 可以看到有Hello World返回說明應用在flask框架下運行沒有問題。

[root@localhost ~]# curl http://127.0.0.1:5000/
Hello World!

三、安裝及配置uwsgi

uWSGI是一個Web Server,並且獨佔uwsgi協議,但是同時支持WSGI協議、HTTP協議等,它的功能是把HTTP協議轉化成語言支持的網絡協議供python使用。有點類似於Java的web服務容器中間件tomcat

1、安裝uwsgi

通過pip命令安裝

(flask_web) [root@localhost flask_web]# pip install uwsgi

如果順利的話會顯示Successfully installed uwsgi-2.0.20,表示安裝成功了。

2、配置uwsgi

新建一個uwsgi.ini配置文件,並將配置信息複製到配置文件
vi uwsgi.ini

[uwsgi]
#http=127.0.0.1:3366  #如果是http,通過proxy_pass http鏈接
socket=127.0.0.1:3366 #如果是socket,通過nginx配置uwsgi_pass socket鏈接
wsgi-file=/home/flask_web/hello.py
callable=app
touch-reload=/home/flask_web/
#最大請求數,最多請求5000次就重啓進程,以防止內存泄漏
max-requests=5000
#請求超時時間,超過60秒關閉請求
harakiri=60
#進程的數量
processes=1
#線程數
threads = 2
#記錄pid的文件
pidfile=/home/flask_web/uwsgi.pid
buffer-size = 32768
#日誌最大50M
log-maxsize=50000000
#配置虛擬環境路徑,如果是在虛擬環境下啓動,這個一定要配,不配會有些包找不到,應用會報錯。可以在uwsgi.log文件中看報錯信息
virtualenv =/home/flask_web
#uwsgi日誌文件,如果是通過supervisor託管,daemonize配置需要屏蔽
#daemonize=/home/flask_web/uwsgi.log
#項目更新後,自動加載
python-autoreload=1
#狀態檢測地址
stats = 127.0.0.1:9191

3、運行uwsgi

(flask_web) [root@localhost flask_web]# uwsgi --ini /home/flask_web/uwsgi.ini

啓動以後通過訪問curl http://127.0.0.1:3366有Hello World!的返回信息表示uwsgi已經成功啓動,並且應用程序正常。

[root@localhost flask_web]# curl http://127.0.0.1:3366
Hello World!

四、配置Nginx反向代理

ps -ef|grep nginx 找到nginx的配置文件
nginx配置文件如果uwsgi配置的是socket連接
[uwsgi]
socket=127.0.0.1:3366 #如果是socket,通過nginx配置uwsgi_pass socket鏈接
nginx的server配置如下:

 server {
      listen 808;
      server_name localhost;

      location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:3366;
       }
       access_log /home/flask_web/access.log;
       error_log /home/flask_web/error.log;
   }

如果uwsgi配置的是http
[uwsgi]
http=127.0.0.1:3366 #如果是http,通過proxy_pass http鏈接
nginx的server配置如下:

server {
      listen 808;
      server_name localhost;

      location / {
           proxy_pass http://127.0.0.1:3366;
       }
       access_log /home/flask_web/access.log;
       error_log /home/flask_web/error.log;
   }

重新加載nginx配置後,通過瀏覽器訪問可以正常顯示訪問結果

五、通過Supervisor進行進程託管

生產環境中,可以通過supervisor來進行uwsgi和nginx進程的託管,界面化的方式管理uwsgi和nginx,包括進程的監控、啓停等。

1、安裝supervisor

通過pip安裝

pip install supervisor

離線安裝請參考:http://xiejava.ishareread.com/posts/d670c9b8/

2、配置supervisor

找到supervisord的安裝目錄在/usr/local/bin下

[root@localhost bin]# which supervisord
/usr/local/bin/supervisord

cd到/usr/local/bin目錄下
通過echo_supervisord_conf > supervisord.conf

[root@localhost bin]# echo_supervisord_conf > supervisord.conf

可以看到生成了一個supervisord.conf的配置文件。
將生成的supervisord.conf配置文件放到/etc/目錄下

mv supervisord.conf /etc/

修改supervisord.conf的配置文件,主要是將子配置文件路徑開啓並指定配置文件路徑,按照慣例將配置文件放到/etc目錄下

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

supervisord.conf配置文件

我們在/etc目錄下建個supervisord.d目錄用來保存supervisor託管進程的配置文件

[root@localhost ~]# cd /etc/
[root@localhost etc]# mkdir supervisord.d

建立並配置子配置文件

[root@localhost etc]# cd supervisord.d/
[root@localhost supervisord.d]# vi uwsgi.ini

複製以下內容至uwsgi.ini文件中

[program:uwsgi]
command =uwsgi --ini /home/flask_web/uwsgi.ini
directory=/home/flask_web
startsecs=10
startretries=5
autostart=true
autorestart=true
stdout_logfile=/home/flask_web/uwsgi_sup_log.log
stdout_logfile_maxbytes=10MB
user=root
stopasgroup=true
killasgroup=true

3、啓動supervisor

在啓動supervisor拉起uwsgi前兩個注意事項

  1. uwsgi的配置文件中daemonize一定要屏蔽掉,否則守護進程一直會重啓,導致端口每次都被佔用,Supervisor託管不了。
    uwsgi.ini
  2. 在啓動之前先將已經啓動的uwsgi進程停掉,否則通過supervisor拉起uwsgi進程時端口衝突
    kill uwsgi進程

啓動supervisord進程

[root@localhost bin]# supervisord -c /etc/supervisord.conf

修改配置文件後重新加載可以通過 supervisorctl reload 命令重新加載
查看supervisor託管狀態

[root@localhost supervisord.d]# supervisorctl status
uwsgi                            STARTING 

可以看到uwsgi被supervisor託管並已經啓動。如果需要通過supervisor的web控制界面進行進程的管理。需要修改/etc/supervisord.conf的配置文件將訪問的IP地址限制放開,設置用戶名、口令

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

重新啓動supervisor,重啓時會報需要驗證的錯誤

[root@localhost supervisord.d]# supervisorctl shutdown
Server requires authentication
error: <class 'xmlrpc.client.ProtocolError'>, <ProtocolError for 127.0.0.1/RPC2: 401 Unauthorized>: file: /usr/local/lib/python3.8/site-packages/supervisor/xmlrpc.py line: 542

可以直接kill -9殺掉supervisor的進程再啓動,也可以通過supervisorctl 輸入用戶名、口令通過shutdown然後再重啓。
啓動命令:supervisord -c /etc/supervisord.conf

這時就可以通過supervisor的web控制界面進行進程的管理了。
Supervisor
至此,CentOS7下python3+Flask+uWSGI+Nginx+Supervisor環境全部搭建好了。

作者博客:http://xiejava.ishareread.com/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章