文章目录
简介
- Nginx:HTTP 服务器,可反向代理、负载均衡等。
- Gunicorn:实现了 WSGI 的 HTTP 服务器,使用便捷。
- gevent:基于协程的 Python 高性能并发网络库。
- Flask:Web 框架,处理请求。
- Supervisor:守护进程,避免因异常错误导致程序长时间中断。
本文以 Ubuntu 18.04 和 CentOS 8.2 为例。
默认当前用户 Ubuntu 为 ubuntu,CentOS 为 root。
pip
可能要换为 pip3
,根据服务器情况而定。
Ubuntu
公共包
sudo -H pip3 install gunicorn
sudo -H pip3 install supervisor
虚拟环境
sudo -H pip3 install virtualenv
sudo mkdir -p /Envs
cd /Envs
sudo virtualenv test
source /Envs/test/bin/activate
deactivate
Python 包
虚拟环境安装
source /Envs/test/bin/activate
sudo pip3 install gevent
sudo pip3 install flask
创建代码
mkdir -p /tmp/code/test
cd /tmp/code/test
vim app.py
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!\n'
@app.route('/api/v1/say/')
def say(message):
return f'{message}\n'
if __name__ == '__main__':
app.run()
Gunicorn 启动程序。第一个 app 是 Python 文件路径,第二个 app 是 Flask 实例名。推荐阅读:Gunicorn使用手册
gunicorn -w 4 -b 127.0.0.1:5000 -k gevent app:app
root 用户可能报错 ModuleNotFoundError: No module named ‘zope.event’,切换回普通用户即可:
exit
测试
curl 127.0.0.1:5000
curl 127.0.0.1:5000/api/v1/say/Hello
Nginx
安装 Nginx
sudo apt-get update
sudo apt-get install nginx
修改 Nginx 配置
sudo vim /etc/nginx/sites-available/default
关键内容如下
server {
location / {
proxy_pass http://127.0.0.1:5000;
}
location ^~ /api/v1/ {
proxy_pass http://127.0.0.1:5000/api/v1/;
}
}
验证 Nginx 配置
sudo nginx -t
重载 Nginx
sudo nginx -s reload
查看进程
ps -ef | grep nginx
查看公网 IP
curl ifconfig.me
访问公网 IP http://xx.xx.xx.xx/
访问接口 http://xx.xx.xx.xx/api/v1/say/Hello
效果
; 守护进程
Ctrl + C 退出以上 gunicorn 程序
创建 supervisor 配置文件
sudo bash -c "echo_supervisord_conf > /etc/supervisord.conf"
创建 supervisor 子进程配置文件路径
sudo mkdir -p /etc/supervisor/conf.d/
修改 supervisor 配置文件
sudo vim /etc/supervisord.conf
将最后一部分改为
[include]
files=/etc/supervisor/conf.d/*.conf
启动 supervisord
supervisord -c /etc/supervisord.conf
查看 supervisord 进程状态(还没配程序,此时空输出)
supervisorctl status
创建 supervisord 子进程配置文件
sudo vim /etc/supervisor/conf.d/app.conf
内容如下
[program:app] ; 项目名
directory=/tmp/code/test ; 工作路径
command=gunicorn -w 4 -b 127.0.0.1:5000 -k gevent app:app ; 脚本执行命令
priority=999 ; 相对启动优先级,数值越小越优先,默认为999
autostart=true ; 在supervisor启动时自动启动,默认为true
autorestart=true ; 在意外退出时重新启动,默认为true
startsecs=10 ; 子进程启动多少秒后状态为running则认为启动成功,默认为1
startretries=3 ; 尝试启动的最大次数,默认为3
exitcodes=0,2 ; 进程的预期退出代码列表,默认为0
stopsignal=QUIT ; 终止进程的信号,默认为TERM
stopwaitsecs=10 ; 在SIGKILL之前等待的最大秒数,默认为10
user=ubuntu ; 在某用户下设置uid来启动程序,默认不切换用户
redirect_stderr=true ; 是否重定向stdout和stderr,默认为false
stdout_logfile=/tmp/app.stdout.log ; stdout的输出文件,默认为AUTO
stdout_logfile_maxbytes=50MB ; stdout最大文件大小,默认为50MB
stdout_logfile_backups=10 ; stdout文件备份数,设为0则不备份,默认为10
重新读取配置并更新子进程
supervisorctl reread
supervisorctl update
再次查看进程状态
supervisorctl status
watch -n 1 "supervisorctl status"
查看公网 IP
curl ifconfig.me
访问公网 IP http://xx.xx.xx.xx/
访问接口 http://xx.xx.xx.xx/api/v1/say/Hello
重启指定子进程(修改程序后执行)
supervisorctl restart app
CentOS
公共包
pip install supervisor
虚拟环境
pip install virtualenv
mkdir -p /Envs
cd /Envs
virtualenv test
source /Envs/test/bin/activate
deactivate
Python 包
虚拟环境安装
source /Envs/test/bin/activate
pip install gunicorn
pip install gevent
pip install flask
创建代码
mkdir -p ~/code/test
cd ~/code/test
vim app.py
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!\n'
@app.route('/api/v1/say/')
def say(message):
return f'{message}\n'
if __name__ == '__main__':
app.run()
Gunicorn 启动程序。第一个 app 是 Python 文件路径,第二个 app 是 Flask 实例名。推荐阅读:Gunicorn使用手册
gunicorn -w 4 -b 127.0.0.1:5000 -k gevent app:app
测试
curl 127.0.0.1:5000
curl 127.0.0.1:5000/api/v1/say/Hello
Nginx
安装 Nginx
yum -y install epel-release
yum install dnf
sudo dnf install nginx
sudo systemctl start nginx
sudo systemctl enable nginx
sudo dnf install firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --list-all
sudo firewall-cmd --reload
修改 Nginx 配置
vim /etc/nginx/nginx.conf
关键内容如下
server {
location / {
proxy_pass http://127.0.0.1:5000;
}
location ^~ /api/v1/ {
proxy_pass http://127.0.0.1:5000/api/v1/;
}
}
验证 Nginx 配置
nginx -t
重载 Nginx
nginx -s reload
查看进程
ps -ef | grep nginx
查看公网 IP
curl ifconfig.me
访问公网 IP http://xx.xx.xx.xx/
访问接口 http://xx.xx.xx.xx/api/v1/say/Hello
效果
; 守护进程
Ctrl + C 退出以上 gunicorn 程序
创建 supervisor 配置文件
echo_supervisord_conf > /etc/supervisord.conf
创建 supervisor 子进程配置文件路径
mkdir -p /etc/supervisor/conf.d/
修改 supervisor 配置文件
sudo vim /etc/supervisord.conf
将最后一部分改为
[include]
files=/etc/supervisor/conf.d/*.conf
启动 supervisord
supervisord -c /etc/supervisord.conf
查看 supervisord 进程状态(还没配程序,此时空输出)
supervisorctl status
创建 supervisord 子进程配置文件
vim /etc/supervisor/conf.d/app.conf
内容如下
[program:app] ; 项目名
directory=/root/code/test ; 工作路径
command=/Envs/test/bin/gunicorn -w 4 -b 127.0.0.1:5000 -k gevent app:app ; 脚本执行命令
priority=999 ; 相对启动优先级,数值越小越优先,默认为999
autostart=true ; 在supervisor启动时自动启动,默认为true
autorestart=true ; 在意外退出时重新启动,默认为true
startsecs=10 ; 子进程启动多少秒后状态为running则认为启动成功,默认为1
startretries=3 ; 尝试启动的最大次数,默认为3
exitcodes=0,2 ; 进程的预期退出代码列表,默认为0
stopsignal=QUIT ; 终止进程的信号,默认为TERM
stopwaitsecs=10 ; 在SIGKILL之前等待的最大秒数,默认为10
user=root ; 在某用户下设置uid来启动程序,默认不切换用户
redirect_stderr=true ; 是否重定向stdout和stderr,默认为false
stdout_logfile=/tmp/app.stdout.log ; stdout的输出文件,默认为AUTO
stdout_logfile_maxbytes=50MB ; stdout最大文件大小,默认为50MB
stdout_logfile_backups=10 ; stdout文件备份数,设为0则不备份,默认为10
重新读取配置并更新子进程
supervisorctl reread
supervisorctl update
再次查看进程状态
supervisorctl status
watch -n 1 "supervisorctl status"
查看公网 IP
curl ifconfig.me
访问公网 IP http://xx.xx.xx.xx/
访问接口 http://xx.xx.xx.xx/api/v1/say/Hello
重启指定子进程(修改程序后执行)
supervisorctl restart app
常用命令
重启指定子进程(修改程序后执行)
supervisorctl restart app
切换到 root 用户
sudo -i
参考文献
- Nginx
- Nginx Documentation
- Gunicorn
- Gunicorn Documentation
- gevent Documentation
- Flask Documentation
- Supervisor Documentation
- Ubuntu设置和查看环境变量
- ubuntu-设置系统环境变量
- WARNING: The script pip3.8 is installed in ‘/usr/local/bin’ which is not on PATH
- python 安装包的默认路径与更改
- How do I install a pip package globally instead of locally
- Linux sudo命令 | 菜鸟教程
- gunicorn 报错 Worker failed to boot. 解决办法
Original: https://blog.csdn.net/lly1122334/article/details/125309263
Author: XerCis
Title: Python高并发服务部署——Nginx+Gunicorn+gevent+Flask+Supervisor
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/747380/
转载文章受原作者版权保护。转载请注明原作者出处!