zoukankan      html  css  js  c++  java
  • 2020最新nginx+gunicorn+supervisor部署基于flask开发的项目的生产环境的详细攻略

    本攻略基于ubuntu1804的版本,服务器用的华为云的服务器,python3(python2已经在2020彻底停止维护了,所以转到python3是必须的)欢迎加我的QQ6398903,或QQ群讨论相关技术

    一、准备项目所需要的模块

    你需要把开发环境下用到的包信息全部导出
    `` pip freeze > requirements.txt
    然后,把requirements.txt文件上传服务器

    二、准备生产环境的python虚拟环境

    毕竟生产环境,也可能运行多个python项目,所以需要准备好python的虚拟环境
    ubuntu1804默认只有python3哈,安装虚拟环境需要先安装venv
    ``sudo apt install python3-venv
    创建一个目录用于存放虚拟环境

    mkdir -p /opt/python/
    sudo python3 -m venv myprj     #最后是项目的名字
    . /opt/python/myprj/bin/activate    #激活虚拟环境, 别忘记了前面的点【.】激活之后命令行前面又虚拟环境的名字,说明成功
    pip install --upgrade pip    #先升级一下Pip
    pip intall -r requirements.txt   # 一次安装全部的python模块
    
    

    三、安装gunicorn

    gunicorn是基于wsgi(web 服务网关接口)web服务器,与flask是绝配(一般django用uwsgi)

    pip install gevent   #如果你的项目中没有用到gevent,那么安装gunicorn之前,需要安装一下
    pip install gunicorn 
    deactivate     #退出虚拟环境
    

    可以直接使用gunicorn命令来启动程序,例如
    ``gunicorn -w 4 -b 127.0.0.1:5000 main:app
    【注意】上面的命令,需要在激活虚拟环境的情况下,到项目目录中运行,项目启动文件是main.py 里面又变量名是app的flask的实例
    特别要注意,main.py里面要有

    if __name__ == "__main__":
        app.run()
    

    否则,gunicorn启动项目时,会报错
    下面是常用命令说明:

    -c CONFIG, --config=CONFIG
    # 设定配置文件。
    -b BIND, --bind=BIND
    # 设定服务需要绑定的端口。建议使用HOST:PORT
    -w WORKERS, --workers=WORKERS
    # 设置工作进程数。建议服务器每一个核心可以设置2-4个。
    -k MODULE
    # 选定异步工作方式使用的模块。
    

    四、配置gunicorn的配置信息

    gunicorn直接使用.py文件作为配置文件,所以,里面是支持py语法的

    from gevent import monkey
    monkey.patch_all()
    import multiprocessing
    
    #debug = True
    loglevel = 'debug'
    bind = '127.0.0.1:6000' #绑定与Nginx通信的端口
    pidfile = 'log/gunicorn.pid'
    accesslog = 'log/access.log'
    errorlog = 'log/debug.log'
    #daemon = True
    workers = multiprocessing.cpu_count() * 2 + 1
    worker_class = 'gevent' #默认为阻塞模式,最好选择gevent模式
    

    保存到,项目目录下的conf/guni.conf

    上面的配置文件中,又两个注释的地方,一个注意事项

    1. debug=True 很好理解,就是刚上线时,可以开启,方便发现错误,正式启用要注销
    2. daemon=True 意思是以守护进程的形式运行,适合直接输入gunicorn命令来运行,【注意】但如果您想用supervisor来管理的话,这个要注销
    3. 需要在项目文件中,建立一个log的文件夹,否则报错无法启动,因为我们的日志文件和pid都需要保存在Log目录中

    五、通过配置文件启动gunicorn以及守护进程启动

    把之前的命令,修改一下,
    gunicorn -w 4 -b 127.0.0.1:5000 -c conf/guni.conf main:app 如果conf文件中,又deamon=True,那么将以守护进程在后台中运行 或者使用 nohup gunicorn -w 4 -b 127.0.0.1:5000 -c conf/guni.conf main:app
    这个时候,就可以退出python虚拟环境了
    ``deactivate #退出虚拟环境

    六、配置nginx

    nginx的安装、配置、使用,请看我之前教程2020年ubuntu1804安装nginx最新稳定版1.16详细教程笔记
    接着之前文件接续补充
    在/etc/nginx/conf.d/目录下,新建一个myprj.conf文件,填入下信息

    server {
            listen 80;
            root /data/python/myprj;
            server_name xxx.xx.xxx.xxx;
            location / {
                proxy_set_header x-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_pass http://localhost:6000/; # gunicorn绑定的端口号
            }
            # 配置static的静态文件:
            location ~ ^/static/.*$ {
                root /data/python/myprj;
            }
    }
    

    在配置nginx最容易出现的问题是,静态文件的配置,一旦没有配好,导致图片,css文件无法访问
    Nginx路径location配置中,使用root目录与alias目录的区别

    1. alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的;
     location /static/ {
            alias  /var/www/static/;
        }
    #注意:alias指定的目录后面必须要加上"/",即/var/www/static/不能改成/var/www/static
    
    1. root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
    location /static/ {
            root  /var/www/;
        }
    #注意:location中指定的/static/必须是在root指定的/var/www/目录中真实存在的。
    #两者配置后的访问效果是一样的。 
    
    1. 配置习惯
      一般情况下,在nginx配置中的良好习惯是:
      • 在location / 中配置root目录
      • 在location /somepath/ 中配置alias虚拟目录
    2. nginx加载新的配置
    nginx -t     #一定要先检查,看到成功的信息,
    nginx -s reload
    

    七、安装和配置supervisor

    supervisor是一个python开发的进程管理工具,不光可以管理python项目,java项目,php-pfm后台启动程序都可以管理哦

    1. 安装
      `` sudo apt install supervisor
    2. 配置文件
      到/ect/supervisor/conf.d/目录下,新建myprj.conf文件
      ``vim myprj.conf
      填入如下内容
    [program:aijiaoyu]
    command=/opt/python/myprj./bin/gunicorn -c /data/python/myprj./env/gunc.py main:app
    directory=/data/python/myprj
    user=root
    autorestart=true
    startsecs=10
    startretires=3
    redirect_stderr=true
    stdout_logfile_maxbytes=100MB
    stdout_logfile_backups = 20
    stdout_logfile=/var/log/supervisor/myprj.log
    

    配置文件的简单说明

    program:myprj]   #登记项目名称
    directory=/data/python/myprj
    command=/opt/python/myprj./bin/gunicorn -c /data/python/myprj./env/gunc.py main:app 程序启动命令
    autostart=true       ; 在supervisord启动的时候也自动启动
    startsecs=10         ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
    autorestart=true     ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
    startretries=3       ; 启动失败自动重试次数,默认是3
    user=root          ; 用哪个用户启动进程,默认是root
    priority=999         ; 进程启动优先级,默认999,值小的优先启动
    redirect_stderr=true ; 把stderr重定向到stdout,默认false
    stdout_logfile_maxbytes=100MB  ; stdout 日志文件大小,默认50MB
    stdout_logfile_backups = 20   ; stdout 日志文件备份数,默认是10
    ; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
    stdout_logfile=/var/log/supervisor/myprj.log
    stopasgroup=false     ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
    killasgroup=false     ;默认为false,向进程组发送kill信号,包括子进程
    

    让supervisor更新配置

    sudo supervisorctl update   #更新配置
    sudo supervisorctl reload   #重启
    sudo supervisorctl status  #查看所有项目的情况
    sudo supervisorctl stop/start/restart  项目名称
    

    【注意】一定不能以守护进程启动,否则supervisor会检测不到进程,从而认为进程启动失败

    总结

    每次看别人的博客,都是觉得不完整,所以自己重写了这个教程。一个完成的流程
    如果对你有用,请点个赞,或者关注,欢迎加群一起交流技术

    参考文档:

    1. nginx+uwsgi 和nginx+gunicorn区别、如何部署
    2. gunicorn部署Flask服务
    3. 使用gunicorn部署flask项目
  • 相关阅读:
    Generate profile vspx
    (转)Connect string 中的 Intergrated Security
    删除数据库
    SQL Server问题之The remote procedure call failed. [0x800706be]
    SQL Server 2008 R2如何开启数据库的远程连接
    ubuntu 12.04 sourcelist 更新源
    Ubuntu12.04 命令gedit出错:Could not connect to session bus (
    解决 Ubuntu 12.04 无法调节屏幕亮度的问题
    Eclipse和PyDev搭建完美Python开发环境(Windows篇)
    raw_input() 与 input() __ Python
  • 原文地址:https://www.cnblogs.com/qumogu/p/12823022.html
Copyright © 2011-2022 走看看