在生產環境中通常用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虛擬運行環境。
在目錄下運行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
運行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的配置文件
如果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
我們在/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前兩個注意事項
- uwsgi的配置文件中daemonize一定要屏蔽掉,否則守護進程一直會重啓,導致端口每次都被佔用,Supervisor託管不了。
- 在啓動之前先將已經啓動的uwsgi進程停掉,否則通過supervisor拉起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控制界面進行進程的管理了。
至此,CentOS7下python3+Flask+uWSGI+Nginx+Supervisor環境全部搭建好了。