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
    
    ; 項目目錄
    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
    ; 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
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章