前后端项目部署-3, flask+Gunicorn+gevent+supervisor,docker部署,以及supervisor的使用

####

部署方案flask+Gunicorn+gevent+supervisor

每个组件的作用:

1,. gunicorn:高性能WSGI服务器;

Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。
和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。

目前Gunicorn只能运行在Linux环境中,不支持windows平台

部署 Flask 应用时,为什么会需要 gunicorn 或 uWSGI?

简单说就是 Flask自带的wsgi性能低下

只适合你开发调试的时候用,

线上你必须用Gunicorn+Nginx才能获得更强的性能,和更高的安全性

下面我说一些废话:

django、flask 都有自带的http server,

仅仅是方便我们开发的时候调试代码而已

这些开源框架的维护者不可能投入大量精力来优化自带的wsgi服务器,

他们需要把更多的精力投入到框架自身的优化中,

因为服务器方面已经有Gunicorn/uWSGI、nginx等优秀的开源解决方案

假设我们用自带的来部署到线上,会有什么问题呢?

性能很差,差到不好意思出门见人(如果你的网站就几十个人访问,那性能应该问题不大)

最后我个人建议的方案是 flask+Gunicorn+gevent+supervisor+nginx

所以说为什么使用Gunicorn,简单点就是为了并发。利用异步,提高性能。

 

2. gevent:把Python同步代码变成异步协程的库;

gevent:gunicorn 默认使用同步阻塞的网络模型(-k sync),对于大并发的访问可能表现不够好,我们很方便地顺手套一个gevent来增加并发量

 

3,supervisor:监控服务进程的工具;

web服务跑起来之后,为了保证服务的稳定性,需要加一个收获进程。supervisor非常好用,配置也简单方便,它是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

nginx一般不会莫名其妙被关闭,但gunicorn是一个进程,完成有有可能因为一些原因被关闭或者阻塞,为了保证gunicorn进程,需要使用看护进程插件。这里使用supervisor来解决这个问题。

supervisor专门用户linux端进程管理,

Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。也实现当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程。

###

启动主程序的命令传递:supervisor->gunicorn->flask

###

看着步骤很多,其实除了Gunicorn都不是必须的,Supervisor和Nginx你要是不想使用其实也可以不使用,我说得比较啰嗦,不过其实很容易。

####

第一步,准备一个简单的flask项目,

 

 

 

很简单只需要一个文件,

from flask import Flask

app = Flask(__name__)


@app.route('/')
def alldata():
    return '<h1>Hello World!</h1>'


#
if __name__ == "__main__":
    """初始化,debug=True"""
    app.run(host='0.0.0.0', port=9876, debug=True)

 

 ###

Flask==1.1.2
gevent==21.8.0
gunicorn==20.1.0
supervisor==4.2.2

 

###

第二步,gunicorn 安装,Gevent安装

pip install gunicorn

pip install gevent

pip install  supervisor

###

第三步,在根目录下新建文件 /gunicorn.conf.py

启动测试

gunicorn start:app -c gunicorn.conf.py

用这种py文件的方式启动是比较简单的,

否则就要用命令行的方式启动,比较麻烦:

gunicorn --workers 3 --bind 0.0.0.0:5000  --user nginx --worker-class gevent start:app

 

#####

第四步:supervisor

你要先搞懂,supervisor和gunicorn,和flask的关系,

其次你要搞懂,supervisor和docker的关系,

配置

[supervisord]
nodaemon=true

[program:flask_docker_gunicorn_supervisor]
command=gunicorn -w4 -b0.0.0.0:8888 app:app    ; supervisor启动命令

 

###

第五步,Dockerfile

FROM python:3.8.5-slim-buster

WORKDIR /usr/src/app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .


CMD ["supervisord","-n","-c","supervisord.conf"]

##

第五步构建

完成这两个文件的创建之后,执行如下命令,就可以开始构建Docker镜像:

sudo docker build -t 'testflask' .

构建完成之后,通过如下命令查看镜像列表,可以发现testflask显示在其中:

sudo docker images

 

####

第六步,运行,

接下来,我们可以push镜像到镜像仓库进行分发,这里我们就在本机运行进行演示。
需要注意,公司的私有代码,不要push到公网的镜像仓库上
运行如下命令,临时运行docker镜像:

sudo docker run -it --rm -p 8888:8888 testflask

 


#####

 

supervisor和语言没有关系,任何代码语言都可以使用这个

对于有些进程,我们不希望它出现意外的崩溃,如果万一崩溃了,也希望可以自动能够重启,而不是手动去启动他们,万一半夜崩了,那不得半夜起来重启服务?那滋味一定很酸爽。很典型的一种就是web服务,按照道理来讲,服务器不宕机,应该是需要一直运行下去的。可是天意不可测,万一哪天突然崩了呢?  所以我们需要一种机制,确保web服务崩了依然可以自启。今天要介绍的supervisor就是作为一种进程守护,来监听web服务,一旦web挂掉,supervisor会让其自启。确保web服务器不会处于挂掉状态

 

supervisor安装

pip install supervisor
echo_supervisord_conf > supervisor.conf   # 生成 supervisor 默认配置文件
vim supervisor.conf                       # 修改 supervisor 配置文件,添加 gunicorn 进程管理

 

另外一种安装方法:
配置好yum源后,可以直接安装【本文安装方法】

yum install supervisor
查看安装的版本:

supervisord -v

 

 

######
使用 supervisor 来管理 项目

[program:myapp]
command=/home/rsj217/rsj217/myproject/venv/bin/gunicorn -w4 -b0.0.0.0:2170 myapp:app    ; supervisor启动命令
directory=/home/rsj217/rsj217/myproject                                                 ; 项目的文件夹路径
startsecs=0                                                                             ; 启动时间
stopwaitsecs=0                                                                          ; 终止等待时间
autostart=false                                                                         ; 是否自动启动
autorestart=false                                                                       ; 是否自动重启
stdout_logfile=/home/rsj217/rsj217/myproject/log/gunicorn.log                           ; log 日志
stderr_logfile=/home/rsj217/rsj217/myproject/log/gunicorn.err                           ; 错误日志

 

supervisor的基本使用命令

supervisord -c supervisor.conf                             通过配置文件启动supervisor
supervisorctl -c supervisor.conf status                    察看supervisor的状态
supervisorctl -c supervisor.conf reload                    重新载入 配置文件
supervisorctl -c supervisor.conf start [all]|[appname]     启动指定/所有 supervisor管理的程序进程
supervisorctl -c supervisor.conf stop [all]|[appname]      关闭指定/所有 supervisor管理的程序进程

 

 

 

使用 supervisor 来管理 nginx。这里需要注意一个问题,linux的权限问题。nginx是sudo的方式安装,启动的适合也是 root用户,那么我们现在也需要用 root用户启动supervisor。增加下面的配置文件

[program:nginx]
command=/usr/sbin/nginx
startsecs=0
stopwaitsecs=0
autostart=false
autorestart=false
stdout_logfile=/home/rsj217/rsj217/myproject/log/nginx.log
stderr_logfile=/home/rsj217/rsj217/myproject/log/nginx.err   

####

supervisor 还有一个web的管理界面,可以激活。更改下配置

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

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
username=user              ; should be same as http_username if set
password=123                ; should be same as http_password if set
;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history  ; use readline history if available

 

 

 

 

 

 

 

 

#####

posted @ 2021-10-06 13:40  技术改变命运Andy  阅读(484)  评论(0编辑  收藏  举报