Centos下Nginx+Gunicorn+Django+supervisor项目部署

Centos下Nginx+Gunicorn+Django+supervisor项目部署

  1. 安装需要的包

    yum install python3
    yum install nginx
    yum install gunicorn
    pip install gevent
    pip install supervisor
    

    gunicorn的简单使用,在服务器上任意一个位置新建一个python文件, 文件名自己定义:

    vi testgunicorn.py
    
    # 在testgunicorn.py中输入以下内容
    def app(environ, start_response):
        data = b"Hello, World!\n"
        start_response("200 OK", [("Content-Type", "text/plain"),("Content-Length", str(len(data)))])
        return iter([data])
    
    

    使用gunicorn运行testgunicorn.py, 在testgunicorn.py文件的当前目录输入下面命令:

     gunicorn -w 2 -b 0.0.0.0:18000 testgunicorn:app
    

    在浏览器输入 外网ip:端口 , 如果出现"Hello, World!"即表示gunicorn正常

    Centos下Nginx+Gunicorn+Django+supervisor项目部署_第1张图片

  2. 配置nginx文件

    # 新建一个配置文件,自定义名字,比如命名为hello_nginx.conf
    touch /etc/nginx/conf.d/hello_nginx.conf
    
    # 在/etc/nginx/conf.d/hello_nginx.conf里输入以下内容
    server {
            listen       11111;
            server_name  second.sunshine.site;
            charset utf-8;
            location / {
                proxy_pass http://0.0.0.0:17881; # 这里要配合启动文件使用
                proxy_redirect     off;
                proxy_set_header   Host                 $http_host;
                proxy_set_header   X-Real-IP            $remote_addr;
                proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
                        proxy_set_header   X-Forwarded-Proto    $scheme;
                    }
    
                    location /static {
                alias   /root/hello/static/;
            }
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
        }
    
    
    

    对文件里面配置进行解释:

    server {
            listen       11111;
            server_name  second.sunshine.site; # 访问项目的时候是在浏览器输入: second.sunshine.site:11111,second.sunshine.site是我的域名,也可以换成外网ip,
            charset utf-8;
    
            location / {
                proxy_pass http://0.0.0.0:17881; # 浏览器输入: second.sunshine.site:11111会去访问本地的17881端口起的进程
                proxy_redirect     off;
                proxy_set_header   Host                 $http_host;
                proxy_set_header   X-Real-IP            $remote_addr;
                proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
                        proxy_set_header   X-Forwarded-Proto    $scheme;
                    }
    
                    location /static {
                alias   /root/hello/static/; # 托管这个路径下hello项目的静态文件
            }
    
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
        }
    
    
  3. 将django项目和nginx连接在一起

    (1)在项目根目录创建一个gunicorn.py文件.(就是有manage.py的那个目录)
    vi gunicorn.py
    
    (2)在文件中输入以下内容
    # coding:utf-8
    import multiprocessing
    bind = '0.0.0.0:17881'      #绑定ip和端口号
    backlog = 512                #监听队列
    chdir = '/root/hello'  #gunicorn要切换到的目的工作目录, 项目的根目录
    timeout = 30      #超时
    worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
    
    workers = multiprocessing.cpu_count() * 2 + 1    #进程数
    threads = 2 #指定每个进程开启的线程数
    loglevel = 'info' #日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
    access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'    #设置gunicorn访问日志格式,错误日志无法设置
    
    accesslog = "/root/hello/gunicorn_log/gunicorn_access.log"      #访问日志文件
    errorlog = "/root/hello/gunicorn_log/gunicorn_error.log"        #错误日志文件
    

    配置文件gunicorn.py中的bind 和chdir将nginx, 项目目录和gunicorn连接在一起了

  4. 启动项目, 有三种方法:

    (1) 第一种方法:命令启动(不推荐,一般不这样操作)

    # 在gunicorn.py目录下执行命令gunicorn Django_project.wsgi -c gunicorn.py, 比如我的项目叫hello:
    gunicorn hello.wsgi -c gunicorn.py
    

    (2)第二种方法:使用脚本

    # 在根目录下(即有manage.py的那个目录下), 创建restart.sh
    touch restart.sh
    
    # 在restart.sh下输入以下内容:
    
    #!/bin/sh
    ## service name
    #项目的目录
    SERVICE_DIR=/root/hello
    #gunicorn的名字
    SERVICE_NAME=gunicorn
    #gunicorn的配置文件名
    SERVICE_CONF=gunicon.py
    #pid存放的位置
    PID=gunicorn\.pid
    #export PATH=$PATH:$HOME/bin:/usr/local/python3/bin
    export PATH=$PATH:$HOME/bin:/usr/bin
    cd $SERVICE_DIR
    
    start(){
           
           nohup gunicorn hello.wsgi -c $SERVICE_DIR/gunicorn.py>/dev/null 2>&1 &
           echo $! > $SERVICE_DIR/$PID
           echo "*** start $SERVICE_NAME ***"
    }
    stop(){
           
           kill `cat $SERVICE_DIR/$PID`
           rm -rf $SERVICE_DIR/$PID
           echo "*** stop $SERVICE_NAME ***"
    
           sleep 2
           P_ID=`ps -ef | grep -w "$SERVICE_NAME" | grep -v "grep" | awk '{print $2}'`
           if [ "$P_ID" == "" ]; then
               echo "*** $SERVICE_NAME process not exists or stop success ***"
           else
               echo "*** $SERVICE_NAME process pid is:$P_ID ***"
               echo "*** begin kill $SERVICE_NAME process,kill is:$P_ID ***"
               kill -9 $P_ID
           fi
    }
    f_usage() {
           
       echo "USAGE: restart [options]"
       echo "OPTIONS:"
       echo "       start"
       echo "       stop "
       echo "       restart"
    }
    case "$1" in
    
       "start")
           start
           ;;
       "stop")
           stop
           ;;
       "restart")
           stop
           sleep 2
           start
           echo "*** restart $SERVICE_NAME ***"
           ;;
       *)
       f_usage
       ;;
    
    esac
    exit 0
    

    运行脚本: ./restart.sh start

    (3)第三种方法: 使用supervisor启动项目; supervisor是用来管理进程的,这里可以用来管理gunicorn进程, 配置步骤如下:

    ​ a. 在/etc目录下创建如下目录结构

    ├── supervisor
    │   ├── conf.d
    │   └── var
    │       ├── log
     └── supervisord.conf
    

    命令如下:

    mkdir -p /etc/supervisor/conf.d
    mkdir -p /etc/supervisor/var/log
    cd /etc
    echo_supervisord_conf > supervisord.conf
    

    b. 修改supervisord.conf

    首先找到 [unix_http_server] 版块,将 file 设置改为如下的值:

    [unix_http_server]
    file=/etc/supervisor/var/supervisor.sock
    

    即让 socket 文件生成在 /etc/supervisor/var目录下

    c. 修改 [supervisord] 板块下的 logfile 和 pidfile 文件的路径,还有 user 改为系统用户,这样 supervisor 启动的进程将以系统用户运行,避免可能的权限问题:

    logfile=/etc/supervisor/var/log/supervisord.log
    pidfile=/etc/supervisor/var/supervisord.pid
    user=root
    

    d. 修改[supervisorctl] 板块:

    serverurl=unix:///etc/supervisor/var/supervisor.sock
    

    e. [include] 版块,将 /etc/supervisor/conf.d/ 目录下所有以 .ini 结尾的文件内容包含到配置中来,这样便于配置的模块化管理,和之前 Nginx 配置文件的处理方式是类似的。

    files = /etc/supervisor/conf.d/*.ini
    

    f: 到 conf.d 新建应用的配置:

    [program:hello]
    command=gunicorn hello.wsgi -c /root/hello/gunicorn.py
    directory=/root/hello
    autostart=true
    autorestart=unexpected
    user=root
    stdout_logfile=/etc/supervisor/var/log/hello-stdout.log
    stderr_logfile=/etc/supervisor/var/log/hello-stderr.log
    

    [program:hello] 指明运行应用的进程,名为 hello。

    command 为进程启动时执行的命令。

    directory 指定执行命令时所在的目录。

    autostart 随 Supervisor 启动自动启动进程。

    autorestart 进程意外退出时重启。

    user 进程运行的用户,防止权限问题。

    stdout_logfile,stderr_logfile 日志输出文件

    g. 启动supervisor:

    supervisord -c /etc/supervisord.conf
    
  5. 在浏览器访问: second.sunshine.site:11111

    Centos下Nginx+Gunicorn+Django+supervisor项目部署_第2张图片
    最后/etc/supervisor生成的文件夹是这样的

├── conf.d
│?? ├── hello.ini
└── var
    ├── log
    │?? ├── hello-stderr.log
    │?? ├── hello-stdout.log
    │?? └── supervisord.log
    ├── supervisord.pid
    └── supervisor.sock

项目/root/hello最终的文件夹是这样的

├── db.sqlite3
├── gunicorn_log
│   ├── gunicorn_access.log
│   └── gunicorn_error.log
├── gunicorn.pid
├── gunicorn.py
├── hello
│   ├── asgi.py
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── __pycache__
│   └── gunicorn.cpython-36.pyc
├── restart.sh
└── static

以下是一些常用命令及参考文章:

gunicorn -w 2 -b 0.0.0.0:18000 testgunicorn:app
supervisord -c /etc/supervisord.conf
supervisorctl -c /etc/supervisord.conf status
gunicorn Djanfo_project.wsgi -c gunicorn.py
./restart.sh start
supervisorctl shutdown
supervisorctl status
supervisorctl update
supervisorctl reload
supervisorctl -c /etc/supervisord.conf start program_name
supervisorctl -c /etc/supervisord.conf stop program_name
supervisorctl -c /etc/supervisord.conf restart program_name
supervisorctl -c /etc/supervisord.conf start all
supervisorctl -c /etc/supervisord.conf stop all

Django+gunicorn+nginx项目部署 - 修仙小白 - 博客园 (cnblogs.com)

使用 Supervisor 管理服务器后台进程 - 知乎 (zhihu.com)

nginx + gunicorn + supervisor 部署 django 项目 - SegmentFault 思否

Nginx+Gunicorn+Supervisor 部署 Django 博客应用_HelloDjango - Django博客教程(第二版)_追梦人物的博客 (zmrenwu.com)

用supervisor管理python进程 | 酷python (coolpython.net)

Supervisor (进程管理利器) 使用说明 - 运维笔记 - 散尽浮华 - 博客园 (cnblogs.com)

Error: class uri 'gevent' invalid or not found: 

[Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py", line 13, in 
    import gevent
ModuleNotFoundError: No module named 'gevent'
raise RuntimeError("gevent worker requires gevent 1.4 or higher")
RuntimeError: gevent worker requires gevent 1.4 or higher

# 出现上面的报错就需要安装1.4版本以上的gevent

# 安装gevent的时候也许会发生greenlet的错
ERROR: Cannot uninstall 'greenlet'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

# 执行命令
yum install -y python3-devel
pip  install --ignore-installed greenlet 
pip3 install gevent

出现上面的报错就需要安装1.4版本以上的gevent

安装gevent的时候也许会发生greenlet的错

ERROR: Cannot uninstall ‘greenlet’. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

执行命令

yum install -y python3-devel
pip  install --ignore-installed greenlet 
pip3 install gevent

你可能感兴趣的:(python,develop)