nginx + vue + django(uwsgi + channels) + supervisor 部署(方案二)

1.环境信息

  • 服务器为centos7
    

2.安装supervisor

  • yum install supervisor
    
  • 友情提示:如果安装失败按照以下三步走,然后再次安装

    第一步:直接更换镜像源,别看网上那些没用的(如果你想重蹈覆辙的话)

    第二步:安装EPEL源
    yum -y install epel-release

    第三步:更新yum源
    yum --skip-broken update
    yum clean all
    yum -y upgrade

3.更换镜像源

  • 如果你上一步安装没有问题,那就跳过该步骤

    1.进入到yum的源目录下
    cd /etc/yum.repos.d/
    
    2.将原来的CentOS-Base.repo进行备份
    mv CentOS-Base.repo CentOS-Base.repo_back
    
    3.下载阿里源
    wget http://mirrors.aliyun.com/repo/Centos-7.repo
    
    4.改变名字
    mv Centos-7.repo CentOS-Base.repo
    
    5.更新
    yum --skip-broken update
    
    6. 清除缓存
    yum clean all
    
    7. 升级
    yum -y upgrade
    
    8.生成缓存
    yum makecache
    

4. 查看supervisor配置文件

  • vi /etc/supervisord.conf
    
    ; Sample supervisor config file.
    
    [unix_http_server]  # socket通讯相关配置
    ...
    
    ;[inet_http_server]  # Web Server配置,如果想使用web界面管理的话,可以去掉前面的;号。port写你服务器的ip,端口可以改称自己喜欢的,默认9001, 建议打开用户名密码验证, 生产环境不建议打开web界面管理。
    ...
    
    [supervisord]  # 服务端程序
    ...
    
    [rpcinterface:supervisor]  # 这个选项是给XML_RPC用的,当然你如果想使用supervisord或者web server 这个选项必须要开启的
    ...
    
    [supervisorctl]  # client端程序
    ...
    
    ;[program:theprogramname]  # 要管理的子进程
    ...
    
    ;[eventlistener:theeventlistenername]  # 和program的地位是一样的,也是suopervisor启动的子进程,不过它干的活是订阅supervisord发送的event。他的名字就叫listener了。我们可以在listener里面做一系列处理,比如报警等等
    ...
    
    ;[group:thegroupname]  # 给programs分组,划分到组里面的program。我们就不用一个一个去操作了我们可以对组名进行统一的操作。 注意:program被划分到组里面之后,就相当于原来的配置从supervisor的配置文件里消失了。。。supervisor只会对组进行管理,而不再会对组里面的单个program进行管理了
    ;programs=progname1,progname2  # 组成员,用逗号分开
    ;priority=999                  # 优先级,相对于组和组之间说的
    ... 
    
    [include]
    files = supervisord.d/*.ini
    
    • 我们只需要关心最后的include,此处告诉我们,手动创建的环境管理配置文件应该放在/etc/supervisord.d目录下,并且文件名必须以.ini结尾。

5. 新建supervisor配置文件

  • 最好一个服务启动命令新建一个配置文件

    1. 新建django服务启动配置
    vi /etc/supervisord.d/django.ini
    
    [program:django]
    
    ; 使用daphne启动
    ; command=/usr/local/python3/bin/daphne -b 0.0.0.0 -p 8888 ECloudBM.asgi:application
    
    ; 不使用daphne启动
    command=/root/.pyenv/versions/qingyun/bin/python3 manage.py runserver 0.0.0.0:8888
    
    ; 项目路径
    directory=/root/projects/ECloud-BM  
    
    ; 启动优先级(越小越优先)
    priority=9999                  
    
    ; 启动 5 秒后没有异常退出,就当作已经正常启动了
    startsecs = 5        
    
    ; 程序异常退出后自动重启
    autorestart = true   
    
    ; 启动失败自动重试次数,默认是 3
    startretries = 3     
    
    ; 标准输出日志
    stdout_logfile = /var/log/supervisor.log
    
    2.启动
    supervisord -c /etc/supervisord.conf
    或者
    systemctl status supervisord.service
    
    • 查看状态
    supervisorctl status django
    
    • 停止
    supervisorctl stop django
    
    • 启动
    supervisorctl start django
    
    • 重启
    supervisorctl restart django
    
    3. 新建celery-worker异步任务启动配置文件
    vi /etc/supervisord.d/celery_worker.ini
    
    [program:celery_worker]
    
    ; 启动项目时运行的命令
    command=/root/.pyenv/versions/qingyun/bin/celery -A ECloudBM worker -l info
    
    ; 项目绝对路径
    directory=/root/projects/Ecloud-BM
    
    ; 是否自动启动
    autostart=true
    
    ; 程序意外退出是否自动重启
    autorestart=true
    
    ; 自动重启间隔
    startsecs=10
    
    ; 杀进程的信号
    stopsignal=QUIT
    
    ; 向进程发出stopsignal后等待OS向supervisord返回SIGCHILD 的时间。若超时则supervisord将使用SIGKILL杀进程
    stopwaitsecs=60
    
    ; 子进程的stdout的日志路径 输出日志文件
    stdout_logfile= /var/log/supervisor/celery_worker.log
    
    ; 错误日志文件 当redirect_stderr=true。这个就不用
    stderr_logfile= /var/log/supervisor/celery_worker_error.log
    
    ; 优先级
    priority=1000
    
    4. 新建celery-beat定时任务启动配置文件
    vi /etc/supervisord.d/celery_beat.ini
    
    [program:celery_beat]
    
    ; 启动项目时运行的命令
    command=/root/.pyenv/versions/qingyun/bin/celery -A ECloudBM beat -l info
    
    ; 项目绝对路径
    directory=/root/projects/Ecloud-BM
    
    ; 是否自动启动
    autostart=true
    
    ; 程序意外退出是否自动重启
    autorestart=true
    
    ; 自动重启间隔
    startsecs=10
    
    ; 杀进程的信号
    stopsignal=QUIT
    
    ; 向进程发出stopsignal后等待OS向supervisord返回SIGCHILD 的时间。若超时则supervisord将使用SIGKILL杀进程
    stopwaitsecs=60
    
    ; 子进程的stdout的日志路径 输出日志文件
    stdout_logfile= /var/log/supervisor/celery_beat.log
    
    ; 错误日志文件 当redirect_stderr=true。这个就不用
    stderr_logfile= /var/log/supervisor/celery_beat_error.log
    
    ; 优先级
    priority=1001
    
    6. 新建celery-flower启动配置文件(用于查看异步任务资源占用率以及执行情况)
    [program:flower]
    
    ; 启动命令
    command=/root/.pyenv/versions/qingyun/bin/flower -A ECloudBM --address=10.10.8.179 --port=5555 --basic_auth=admin:password@
    
    ; 项目目录
    directory=/root/projects/Ecloud-BM
    
    ; 启动优先级
    priority=1002                  ; the relative start priority (default 999)
    
    ; 启动 5 秒后没有异常退出,就当作已经正常启动了
    startsecs = 5        
    
    ; 程序异常退出后自动重启
    autorestart = true   
    
    ; 启动失败自动重试次数,默认是 3
    startretries = 3     
    
    ; 错误日志
    stdout_logfile = /var/log/supervisor/celery_flower.log
    
    ; 标准输出日志
    stderr_logfile= /var/log/supervisor/celery_flower_error.log
    
    5. 新建uwsgi启动配置文件(后面结合nginx进行并发处理,注意,此处如果使用uwsgi启动django项目,则去掉django.ini这个启动配置)
    • uwsgi.ini(建议放在项目根目录下,与manage.py同级别),内容如下:
    [uwsgi]
    
    ; 使用nginx连接时使用
    ; socket = 10.10.8.179:10000
    
    ; 直接做web服务器使用,指定要监听的ip和端口号,即我们运行项目时的ip和端口
    http = 10.10.8.179:9000
    
    ; 项目目录
    chdir = /root/projects/Ecloud-BM
    
    ; 项目中的wsgi.py文件的目录,相对于项目目 = Ecloud-BM.wsgi
    module = ECloudBM.wsgi:application
    
    ; 静态文件映射,测试uwsgi配置时为了能够访问到静态资源,所以加上这个配置。在使用nginx时,需要注销掉这个配置,改用nginx来代理静态资源访问
    ; 可使用 python manage.py collectstatic
    static-map=/static=/root/projects/Ecloud-BM/static
    
    ; 指定启动的工作进程数
    processes = 4
    
    ; 指定每个进程中的线程数
    threads = 2
    
    ; 指定在工作进程中存在一个主进程
    master = True
    
    ; 服务停止时自动移除unix Socket和pid文件
    vacuum = True
    
    ; 保存启动之后主进程的进程号
    pidfile = uwsgi.pid
    
    ; 设置uwsgi后台运行,运行信息保存在uwsgi.log(使用supervisor托管时此处一定要注释调)
    ; daemonize = uwsgi.log
    
    ; 单个日志的大小
    buffer-size=32768
    
    ; 设置每个工作进程处理请求的上限,达到上限时,将回收(重启)该进程。可以预防内存泄漏
    max-requests=5000
    
    ; 虚拟环境所在目录
    home=/root/.pyenv/versions/qingyun/
    PYTHONHOME = /root/.pyenv/versions/qingyun/bin/
    
    
    • 使用supervisor管理uwsgi服务,内容如下:
    [program:uwsgi]
    
    ; 启动项目时运行的命令
    command=/root/.pyenv/versions/qingyun/bin/uwsgi uwsgi.ini
    
    ; 项目绝对路径
    directory=/root/projects/Ecloud-BM
    
    ; 是否自动启动
    autostart=true
    
    ; 程序意外退出是否自动重启
    autorestart=true
    
    ; 自动重启间隔
    startsecs=10
    
    ; 杀进程的信号
    stopsignal=QUIT
    
    ; 向进程发出stopsignal后等待OS向supervisord返回SIGCHILD 的时间。若超时则supervisord将使用SIGKILL杀进程
    stopwaitsecs=60
    
    ; 子进程的stdout的日志路径 输出日志文件
    stdout_logfile= /var/log/supervisor/uwsgi.log
    
    ; 错误日志文件 当redirect_stderr=true。这个就不用
    stderr_logfile= /var/log/supervisor/uwsgi_error.log
    
    ; 优先级
    priority=1003
    
    6. 新建asgi启动配置文件(用于channels通信)
    • 如果/run/daphne该路径不存在则需要手动创建
    [program:asgi]
    
    ; channels通信地址
    socket=tcp://10.10.8.179:8889
    
    ; 项目目录
    directory=/root/projects/Ecloud-BM/EcloudBM
    
    ; 启动命令(我使用此命令启动报错,网上也没找到解决办法,如果你也一样,可以使用下面命令启动)
    command=/root/.pyenv/versions/qingyun/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers ECloudBM.asgi:application
    
    ; command=/root/.pyenv/versions/qingyun/bin/daphne -b 10.10.8.179 -p 8889 --proxy-headers ECloudBM.asgi:application
    
    ; 进程数
    numprocs=4
    
    ; 进程名
    process_name=asgi%(process_num)d
    
    ; 自动启动
    autostart=true
    
    ; 自动重启
    autorestart=true
    
    ; 错误日志
    stdout_logfile=/var/log/supervisor/asgi.log
    
    ; 标准输出日志
    stderr_logfile=/var/log/supervisor/asgi_error.log
    
    ; 日志保存上限
    stdout_logfile_maxbytes = 20MB
    

6.使用supervisorctl进行管理

  • 1.查看所有子服务
    (qingyun) [root@localhost supervisord.d]# supervisorctl status
    asgi:asgi0                       STARTING  
    asgi:asgi1                       STARTING  
    asgi:asgi2                       STARTING  
    asgi:asgi3                       STARTING  
    celery_beat                      STARTING  
    celery_worker                    STARTING  
    flower                           STARTING  
    uwsgi                            STARTING 
    supervisor>
    
    • 如果使用supervisorctl管理命令报以下错误:
    (qingyun) [root@localhost ~]# supervisorctl 
    unix:///var/run/supervisor/supervisor.sock no such file
    
    • 请执行如下代码
    (qingyun) [root@www Ecloud-BM]# supervisorctl
    asgi:asgi0                       RUNNING   pid 21529, uptime 0:00:01
    asgi:asgi1                       STARTING  
    asgi:asgi2                       RUNNING   pid 21492, uptime 0:00:03
    asgi:asgi3                       RUNNING   pid 21505, uptime 0:00:01
    celery_beat                      RUNNING   pid 12319, uptime 0:28:09
    celery_worker                    RUNNING   pid 12334, uptime 0:28:07
    flower                           RUNNING   pid 25468, uptime 1:23:50
    uwsgi                            RUNNING   pid 25469, uptime 1:23:50
    supervisor>
    
  • 2.查看可用命令
    supervisor> 
    supervisor> help
    
    default commands (type help <topic>):
    =====================================
    add    exit      open  reload  restart   start   tail   
    avail  fg        pid   remove  shutdown  status  update 
    clear  maintail  quit  reread  signal    stop    version
    
    supervisor> 
    
  • 3.示例如下
    • 查看单个服务错误日志
    supervisor> help tail  # 查看命令使用方式
    tail [-f] <name> [stdout|stderr] (default stdout)
    Ex:
    tail -f <name>		Continuous tail of named process stdout
    			Ctrl-C to exit.
    tail -100 <name>	last 100 *bytes* of process stdout
    tail <name> stderr	last 1600 *bytes* of process stderr
    supervisor> 
    supervisor> 
    supervisor> tail -200 django stderr 
    Listen failure: Couldn't listen on 0.0.0.0:8888: [Errno 98] Address already in use.
    
    supervisor> 
    
    • 停止所有服务
    supervisor> stop all
    asgi:asgi1: stopped
    asgi:asgi0: stopped
    asgi:asgi3: stopped
    celery_beat: stopped
    asgi:asgi2: stopped
    uwsgi: stopped
    celery_worker: stopped
    flower: stopped
    supervisor>
    
    • 启动所有服务
    supervisor> start all
    asgi:asgi1: started
    asgi:asgi0: started
    asgi:asgi3: started
    asgi:asgi2: started
    flower: started
    celery_worker: started
    celery_beat: started
    uwsgi: started
    supervisor>
    
    • 查看服务状态
    supervisor> status
    asgi:asgi0                       STARTING  
    asgi:asgi1                       RUNNING   pid 25414, uptime 0:00:03
    asgi:asgi2                       RUNNING   pid 25417, uptime 0:00:02
    asgi:asgi3                       RUNNING   pid 25416, uptime 0:00:02
    celery_beat                      RUNNING   pid 21789, uptime 0:12:03
    celery_worker                    RUNNING   pid 21788, uptime 0:12:03
    flower                           RUNNING   pid 21790, uptime 0:12:03
    uwsgi                            RUNNING   pid 21791, uptime 0:12:03
    supervisor>
    
    • 退出
    supervisor> quit
    

7.使用web界面管理服务

  • 1.修改配置文件
    vi /etc/supervisord.conf 
    
  • 2.将以下内容前面的;去掉
    [inet_http_server]         ; inet (TCP) server disabled by default
    port=10.10.8.179:9001      ; ip(你服务器的ip地址) + 端口号(根据你的爱好指定)
    username=user              ; web端登录用户名
    password=password          ; web端登录密码
    
  • 3.重载supervisorctl配置
    supervisorctl reload
    

在这里插入图片描述

  • 4.访问后端项目
    • 使用uwsgi启动时指定的端口进行访问(一切正常,现在完全可以通过supervisor的web界面进行管理项目的启停)
      在这里插入图片描述

8.配置开机自启

  • 1.修改配置文件
    vi /lib/systemd/system/supervisord.service
    
  • 2.将以下内容加入到Service下
    ExecStop=/usr/bin/supervisord shutdown 
    ExecReload=/usr/bin/supervisord reload 
    killMode=process
    Restart=on-failure
    RestartSec=42s
    
  • 3.执行开机自启命令
    systemctl enable supervisord
    

9.项目部署(nginx + vue + uwsgi)


  • 项目结构
    在这里插入图片描述

  • 目录说明:

    frontend目录(需要自己创建名称随意,也可以不放在项目内)将前端vue打包生成的dist直接拷贝进来就(nginx配置时写绝对路径到该dist目录)

    将settings.py配置文件DEBUG改为False
    在这里插入图片描述

  • 1.安装nginx
    yum install nginx
    

    在这里插入图片描述

  • 2.新建项目配置文件(重点)
    • 说在前面:此时要通过nginx进行部署,所以一定要修改uwsgi代理的连接方式为socket
      在这里插入图片描述
    # 这是nginx原生配置文件所包含配置信息的目录(它建议将项目配置文件放在此处,而不是在原生配置文件上进行改动)
    cd /etc/nginx/conf.d/
    
    # 文件名随意, 但必须以.conf结尾
    vi xxx.conf
    
    upstream qingyun {
       server 10.10.8.179:10000;  # 与uwsgi服务端口保持一致
    }
    upstream channels-backend {
       server 10.10.8.179:8889;  # 与asgi服务端口保持一致
    }
    
    # 将80端口转发到vue,然后请求接口以api|base|vserver|setup开头则转发到10000端口的uwsgi服务上,将请求接口以ws开头的websocket连接转发到asgi服务上
    
    server {
        listen      80;
        server_name 10.10.8.179; # 你的访问地址, 有域名的话直接写域名
    
        proxy_set_header Cookie $http_cookie;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-real-ip $remote_addr;
    
        location / {
            try_files $uri $uri/ /index.html;  # 此处是重点(指向dist目录下的index.html),如果不配置会自动转发到nginx默认主页
            root /root/projects/Ecloud-BM/frontend/dist; # 这是前端静态文件目录路径
        }
        location ~(api|base|vserver|setup)/  {  # 此处则是前台项目转发给后端的请求接口(即你的项目url可能的开头,以此来进行匹配)
            uwsgi_pass qingyun;  # uwsgi(通用网关接口)转发django请求
            include /etc/nginx/uwsgi_params;
        }
        location ~(ws)/ {  # # 此处则是前台项目转发给后端websocket的请求接口(routing可能的开头,以此来进行匹配)
            try_files $uri @proxy_to_app;  # channels通信转发,需要用到asgi(异步网关协议接口)
        }
        location @proxy_to_app {
            proxy_pass http://channels-backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    
            proxy_redirect off;
            proxy_set_header Host $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-Host $server_name;
        }
    }
    

    说明:

    项目总urls.py示例如下(可能的开头有 base vserver api setup)
    对应配置如下:

    location ~(api|base|vserver|setup)/ {
    	...
    }
    

    在这里插入图片描述
    在这里插入图片描述

    项目总routing.py示例如下(可能的开头有 ws)
    对应配置如下:

    location ~(ws)/ {
    	...
    }
    

    在这里插入图片描述

  • 3. 检查配置文件是否正确 在这里插入图片描述
  • 4. 重新加载配置文件

    在这里插入图片描述

  • 5. 配置nginx开机自启
    • 1.在系统服务目录里创建nginx.service文件

      vi /usr/lib/systemd/system/nginx.service
      
    • 2.在 [Service] 下加入以下内容

      ExecStart=/usr/sbin/nginx
      ExecReload=/usr/sbin/nginx -s reload
      ExecStop=/usr/sbin/nginx -s quit
      
    • 3.设置开机自启动

      systemctl enable nginx.service
      

10.访问


  • 1. 访问10.10.8.179的80端口
    在这里插入图片描述
  • 2. 登录(没有问题,部署成功)
    在这里插入图片描述

11. 使用nginx部署项目中遇到的问题

  • 1. failed (13: Permission denied)
    • 可能性一:

      解决:
      
      cd /etc/nginx/  # 进入nginx目录
      vim nginx.conf  # 编辑nginx.conf
      
      将user xxxx; 修改为 user root;
      
      # 命令重新加载配置
      nginx -s reload 
      
    • 可能性二:

      查看SELinux状态:
      
      1/usr/sbin/sestatus -v      ##如果SELinux status参数为enabled即为开启状态
      
      SELinux status:                 enabled
      
      2、getenforce                 ##也可以用这个命令检查
      
      关闭SELinux:
      
      1、临时关闭(不用重启机器):
      
      setenforce 0                  ##设置SELinux 成为permissive模式
      
                                    ##setenforce 1 设置SELinux 成为enforcing模式
      
      2、修改配置文件需要重启机器:
      
      修改/etc/selinux/config 文件
      
      将SELINUX=enforcing改为SELINUX=disabled
      
      重启机器即可
      
  • 2. 配置了80端口转发,却依然指向默认地址,显示Welcome to nginx界面
    # location没有写index  index.html index.htm;导致项目无法实现重定向
    
    location / {
    	...
    	index  index.html index.htm;
    }
    
    # 命令重新加载配置
    nginx -s reload
    
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值