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
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)/ { ... }
- 說在前面:此時要通過nginx進行部署,所以一定要修改uwsgi代理的連接方式爲socket
-
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.訪問
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