• 前后端项目部署-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

    #####

  • 相关阅读:
    阿里--面经 搜集
    阿里一面经验总结
    System对象
    JDBC-oracle(登陆)
    博客静态页面
    设计模式(1)---Factory Pattern
    软件设计师备考经验(含新旧版本对比)
    第九课,ROS仿真1
    参数服务器相关的问题
    3.空域图像处理的洪荒之力
  • 原文地址:https://www.cnblogs.com/andy0816/p/15371152.html
Copyright © 2020-2023  润新知