1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 【flask】适合生产环境的高并发部署方案(gunicorn + gevent + supervisor)

【flask】适合生产环境的高并发部署方案(gunicorn + gevent + supervisor)

时间:2023-01-20 10:28:19

相关推荐

【flask】适合生产环境的高并发部署方案(gunicorn + gevent + supervisor)

文章目录

1.安装docker镜像2.查看alphin版本3.更换alpine源4.更换pip源5.安装requirements.txt6.安装完成7.启动flask应用8.用gunicorn启动flask应用9.使用supervisor启动gunicorn10.镜像分享

历时两天,构建了基于python的微服务环境,该方案可用于生产环境,再搭配一个Nginx进行反向代理和负债均衡,可满足高并发需求。

技术方案为:python + Flask + gunicorn + gevent + supervisor + Docker

本文主要搭建图中Python运行环境部分

Python:这里没有要求,我用的3.7Flask:Python Web开发中最火的玄冥二老之一(另一个是Django),它最大的特点就是轻量级Gunicorn:熟悉JAVA 或者 PHP 做开发的可能对 Python的应用部署还是有些懵的,Flask应用是一个符合WSGI规范的Python应用,不能单独运行,需要依赖其他的组件提供服务器功能Gevent:Gunicorn 默认使用同步阻塞的网络模型(-k sync),对于高并发的访问并不太友好,所以我们需要使用gevent来提高并发量supervisor:用来守护gunicorn,当进程挂掉后自动重启Dokcer:容器!你也可以把它理解为一个“盒子”。有时候我们会倦于管理项目的部署和维护。如果使用容器封装项目,那么只需要维护一个配置文件完成部署需求,包括后续将整个部署的过程完全自动化,部署就会变得更便捷

简介引用:/qiulin_wu/article/details/105507785

1.安装docker镜像

基础镜像python:3.7-Alpine,提供python环境。

docker pull python:3.7-Alpine

首次启动:

docker run --name python -p 5000:5000 -v G:\docker\share:\tmp\share -i -t python:3.7-alpine

说明:

-p是将flask的5000端口映射出来

-v 是将window的目录映射给容器,用于保存测试代码

创建容器后启动,可配置环境:

docker exec -it 容器ID或name /bin/sh

2.查看alphin版本

查看python版本:

3.更换alpine源

vi /etc/apk/repositories

添加

/alpine/v3.16/main/

/alpine/v3.16/community/

注意:版本号一定要匹配,这里是3.16

更新源:

apk update && apk upgrade

注意:

sed -i ‘s/dl-//g’ /etc/apk/repositories

在每次apk 安装前运行一次,也是有用的

4.更换pip源

(1)在用户根目录下 ~ 下创建 .pip 隐藏文件夹,如果已经有了可以跳过

mkdir ~/.pip

(2)进入 .pip 隐藏文件夹并创建 pip.conf 配置文件

cd ~/.pip && touch pip.conf

(3)新增 pip.conf 配置文件内容

vi pip.conf

[global] index-url = /simple [install] use-mirrors =true mirrors =/simple/ trusted-host =

(4)更新pip:

pip install --upgrade pip

5.安装requirements.txt

默认的库只有3个:

cd /usr/local/python

vi requirements.txt

文件内容:

Flask==1.1.2gunicorn==20.1.0gevent==21.12.0eventlet==0.33.1greenlet==1.1.2pandas==1.3.5numpy==1.19.2celery==5.2.6Jinja2==3.0.3itsdangerous==2.0.1Werkzeug==2.0.2supervisor==4.2.4

其中若没有安装g ++会报错,pandas和numpy安装会报错:

报错:

pandas报错,需要先安装numpy

numpy报错:

RuntimeError: Broken toolchain: cannot link a simple C program

解决办法:

/wxx999/p/16142681.html

需要安装g++!问题解决

sed -i ‘s/dl-//g’ /etc/apk/repositories

apk add --no-cache g++

安装完g++后执行:

pip install -r requirements.txt

6.安装完成

包数量变成47个了

所以安装的不仅是明面上的那几个。

生成的镜像有400多M。

7.启动flask应用

在本地创建文件夹和一个测试工程:

main.py

# coding=utf-8# hello worldfrom flask importFlask#创建应用程序app =Flask(__name__)# 写一个函数来处理浏览器发送过来的请求@app.route("/")#当访问网址时,默认执行下面函数def index():return 'weclometo Rocket!!!'if __name__ == "__main__":# host 需要设置成 0.0.0.0 才能在容器外部访问app.run(host='0.0.0.0', port=5000, debug=True)

gunicorn/config.py

# filename:gunicorn.conf.py# 绑定ip和端口号bind = '0.0.0.0:5000'# 设置守护进程,将进程交给supervisor管理daemon = 'false'# 监听队列backlog = 512# 超时timeout = 30# 使用gevent模式,还可以使用sync 模式,默认的是sync模式worker_class = 'gevent'# 进程数# workers = multiprocessing.cpu_count() * 2 + 1workers = 4# 指定每个进程开启的线程数threads = 2# 设置最大并发量worker_connections = 2000# 设置访问日志路径accesslog = "/tmp/share/flask_logs/access.log"# 设置错误日志路径errorlog = "/tmp/share/flask_logs/debug.log"# 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置loglevel = 'info'

复制工程到容器:

docker cp G:\docker\share\flask_demo python:/tmp/share

G:\docker\share\flask_demo:是window系统下的项目路径

/tmp/share:是容器内的路径(需要先在tmp下创建一个share)

执行启动文件:

python /tmp/share/ flask_demo/main.py

成功启动如下,

可以在window浏览器输入:http://localhost:5000/

8.用gunicorn启动flask应用

cd /tmp/share/flask_demo

启动方式一(基于参数):

gunicorn -w 2 -b 0.0.0.0:5000 main:app

-w 表示2个进程

-b 表示主机地址和端口

main: 表示main.py

可以在window浏览器输入:http://localhost:5000/,仍然可以看到

启动方式二(基于配置文件):

gunicorn -c gunicorn/config.py main:app

此时没有打印信息,但在浏览器可以正常访问,日志保存在配置文件中规定的日志路径:

# 设置访问日志路径accesslog = "/tmp/share/flask_logs/access.log"# 设置错误日志路径errorlog = "/tmp/share/flask_logs/debug.log"

方式三:

nohup gunicorn -c $(pwd)/config.py app:app &> ./logs/uwsgi.log &(没试过)

使用 nohup 使应用始终保持后台运行,并记录相应的日志信息

附加:结束gunicorn服务进程

参考:

使用下面命令找出gunicorn所有进程。

ps -ef | grep gunicorn

[root@VM_0_12_centos ~] ps -ef|grep gunicorn

xxx 19950 17074 0 17:13 pts/2 00:00:00 /home/xxx/anaconda3/bin/python /home/xxx/anaconda3/bin/gunicorn -c gunicorn/config.py app:app

xxx 19968 19950 0 17:13 pts/2 00:00:00 /home/xxx/anaconda3/bin/python /home/xxx/anaconda3/bin/gunicorn -c gunicorn/config.py app:app

xxx 20264 1 0 17:13 pts/1 00:00:00 grep --color=auto gunicorn

然后使用 kill -9 进程ID 命令来杀掉相关进程

[root@VM_0_12_centos ~] kill -9 19950

[root@VM_0_12_centos ~] kill -9 19968

[root@VM_0_12_centos ~] ps -ef | grep gunicorn

杀掉进程后,稍等几秒,再使用ps -ef | grep gunicorn查看,发现gunicorn服务进程已全部杀掉。

9.使用supervisor启动gunicorn

教程:

1./p/3e1f7b8b6214?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2./qq_39146974/article/details/107630717

3./wumian0123/article/details/106614272

(1)创建软连接:

ln -s /usr/local/bin/supervisord /usr/bin/supervisord

ln -s /usr/local/bin/supervisorctl /usr/bin/supervisorctl

(2)生成配置文件:

python3不支持生成配置的命令,所以需要再额外安装python2的supervisor,然后在python3环境下使用python2生成的配置文件。。。(实测可以生成配置)

mkdir /etc/supervisor #创建supervisor,若存在请忽略

mkdir /etc/supervisor/conf.d #创建conf.d,若存在请忽略

echo_supervisord_conf > /etc/supervisor/supervisord.conf 生成配置文件

报错:

原因:可能是没有安装supervisor, pip list确认一下

vim /etc/supervisor/supervisord.conf

改两处:

a.

将末尾的[include]部分改为:

[include]files = /etc/supervisor/conf.d/*.conf

b.

在[supervisord]下面添加**environment=LC_ALL=‘en_US.UTF-8’,LANG=‘en_US.UTF-8’**解决编码问题

(3) 编辑自定义配置文件

在/etc/supervisor/conf.d/目录下创建一个配置文件(用于a的include),如flask_demo.conf,flask_demo是项目名称,这个配置文件是专门用于配置项目的。

vi /etc/supervisor/conf.d/flask_demo.conf

添加以下内容:

版本一:

[program:flask_demo];项目工作目录(脚本启动目录的全路径)directory = /home/rd/xxx;启动命令command = gunicorn -c gunicorn.conf.py app:app;启动时间startsecs = 0;终止等待时间stopwaitsecs = 0;supervisord守护程序启动时自动启动tornadoautostart = true;supervisord守护程序重启时自动重启tornadoautorestart = true;确保关闭supervisord时停止所有相关子进程stopasgroup=true ;确保关闭supervisord时停止所有相关子进程killasgroup=true ;log 日志stderr_logfile=/tmp/share/supervisor_logs/error.log

版本二:

解释更清楚

[program:flask_demo];如果有多个命令,之间用&&分隔command=/home/user/python/python_virtual/flask_app/bin/gunicorn -c /home/user/python/flask_app/config_g.py manager:appdirectory=/home/user/python/flask_app ; 程序(gunicorn)的启动目录,即manger.py所在目录;redirect_stderr=true的时候,stderr也会写进这个日志文件stdout_logfile=/home/user/python/flask_app/log/supervisor_stdout.log ; 记录控制台的输出,很有用,因为gunicorn的日志无法记录控制台的输出stderr_logfile=/home/user/python/flask_app/log/supervisor_stderr.log; 程序中配置的日志,但实际只有warning以上级别的才会记录,所以没什么用;子进程中没有不能设置日志等级autostart=true ;如果是true,子进程将在supervisord启动后被自动启动,默认就是trueautorestart=true;这个是设置子进程挂掉后自动重启的情况,有三个选项,false,true和unexpected。如果为false,无论什么情况下,都不会被重新启动;如果为true,只要子进程挂掉,将会被无条件重启;如果为unexpected,只有子进程异常中断时才会重新启动。startsecs=10 ; 子进程启动多少秒之后,此时状态如果是running,则认为启动成功了priority=997 ;值越大优先级越低

版本一的省略版:(我使用的这个)

有注释可能无法显示中文,可复制无注释版本:

[program:flask_demo]directory = /tmp/share/flask_democommand = gunicorn -c /tmp/share/flask_demo/gunicorn/config.py main:appstartsecs = 0stopwaitsecs = 0autostart = trueautorestart = truestopasgroup=truekillasgroup=truestderr_logfile=/tmp/share/supervisor_logs/error.log

command为gunicorn的启动命令,-c后面为项目中的gunicorn的配置文件,这里命令的写法参考8

注意:需要创建日志路径/tmp/share/supervisor_logs

(4)启动supervisor

supervisord -c /etc/supervisor/supervisord.conf

-c后面的就是前面生成的配置文件,注意这个名字在一些教程中可能是supervisor.conf,我们生成时用的是什么名称,这里就用什么名称。

(5)supervisorctl一些常见的命令:

运行supervisorctl命令,不加参数,会进入supervisor客户端的交互终端

Ÿsupervisorctl status--查看所有子进程状态

Ÿsupervisorctl start/stop/restart子进程名 --开启或停止子进程,都不会载入最新的配置文件

Ÿsupervisorctl reload--重启supervisord服务,载入最新的子进程配置文

Ÿsupervisorctl reread--读取有更新(增加)的配置文件,不会启动新添加的子进程

Ÿsupervisorctl update--重启配置文件修改过的子进程

总结:reload重启所有,而update仅重启更新了配置的,reread好像没什么用(因为仅更新不重启)

显示进程运行成功!,访问浏览器,也能正常访问http://localhost:5000/

注意:网上都说supervisor在python3下可能会出现问题,所以请多留意一下

10.镜像分享

针对上述的操作,我打包了两个镜像到docker hub,可直接pull 使用。

push教程见我的另一篇文章:docker生成镜像并push到docker Hub(附denined:requested access to the resource is denied解决办法)

这里有两个镜像,欢迎大家使用。

docker pull tangzhaoxiang/py3-flask-gunicorn:latest

docker pull tangzhaoxiang/py3-flask-gunicorn:supervisor

简单说明一下:

根据镜像pull和run之后(此处不展开了),需要进入到容器内部:

docker exec -it 容器名 /bin/sh

此时进入到alpine系统里,根据不同的镜像执行不同的启动命令:

tag为lastest的镜像不带superiovisor,其启动方式为gunicorn命令行启动(详见8)

cd /tmp/share/flask_demo

gunicorn -w 2 -b 0.0.0.0:5000 main:app

tag为supervisor 的镜像带superiovisor,其启动方式为supervisor启动(详见9)

supervisord -c /etc/supervisor/supervisord.conf

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。