進程管理工具(Supervisor) 簡介
Supervisor是用Python開發的一個client/server服務,是Linux/Unix系統下的一個進程管理工具,不支持Windows系統。它可以很方便的監聽、啟動、停止、重啟一個或多個進程。用Supervisor管理的進程,當一個進程意外被殺死,supervisort監聽到進程死后,會自動將它重新拉起,很方便的做到進程自動恢復的功能,不再需要自己寫shell腳本來控制。
不使用守護進程會出現的三個問題:
- 1、ASP.NET Core應用程序運行在shell之中,如果關閉shell則會發現 ASP.NET Core程序被關閉,從而導致應用無法訪問,這種情況當然是我們不想遇到的,而且生產環境對這種情況是零容忍的。
- 2、如果 ASP.NET Core進程意外終止那么需要人為連進shell進行再次啟動,往往這種操作都不夠及時。
- 3、如果服務器宕機或需要重啟,我們則還是需要連入shell進行啟動。
為了解決這些問題,我們需要有一個程序來監聽 ASP.NET Core 應用程序的狀況。並在應用程序停止運行的時候立即重新啟動。
二、supervisor安裝
配置好yum源后,可以直接安裝
yum install supervisor
Debian/Ubuntu可通過apt安裝
apt-get install supervisor
pip安裝
pip install supervisor
easy_install安裝
easy_install supervisor
Supervisor安裝與配置
1、安裝Python包管理工具(easy_install)
yum install python-setuptools
2、安裝Supervisor
easy_install supervisor
3、配置Supervisor應用守護
a) 通過運行echo_supervisord_conf程序生成supervisor的初始化配置文件,如下所示:
mkdir /etc/supervisor echo_supervisord_conf > /etc/supervisor/supervisord.conf
然后查看路徑下的supervisord.conf。在文件尾部添加如下配置。
... ;[include]
files = /etc/supervisord.d/*.ini
;conf.d 為配置表目錄的文件夾,需要手動創建
[include] files = conf.d/*.conf![]()
b) 為你的程序創建一個.conf文件,放在目錄"/etc/supervisor/conf.d/"下。
[program:MGToastServer] ;程序名稱,終端控制時需要的標識 command=dotnet MGToastServer.dll ; 運行程序的命令 directory=/root/文檔/toastServer/ ; 命令執行的目錄 autorestart=true ; 程序意外退出是否自動重啟 stderr_logfile=/var/log/MGToastServer.err.log ; 錯誤日志文件 stdout_logfile=/var/log/MGToastServer.out.log ; 輸出日志文件 environment=ASPNETCORE_ENVIRONMENT=Production ; 進程環境變量 user=root ; 進程執行的用戶身份 stopsignal=INT
c) 運行supervisord,查看是否生效
supervisord -c /etc/supervisor/supervisord.conf ps -ef | grep MGToastServer
成功后的效果:
![]()
ps 如果服務已啟動,修改配置文件可用“supervisorctl reload”命令來使其生效
4、配置Supervisor開機啟動
a) 新建一個“supervisord.service”文件
# dservice for systemd (CentOS 7.0+) # by ET-CS (https://github.com/ET-CS) [Unit] Description=Supervisor daemon [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf ExecStop=/usr/bin/supervisorctl shutdown ExecReload=/usr/bin/supervisorctl reload KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target
b) 將文件拷貝至"/usr/lib/systemd/system/supervisord.service"
c) 執行命令
systemctl enable supervisord
d) 執行命令來驗證是否為開機啟動
systemctl is-enabled supervisord
![]()
配置完成啦.
常用的相關管理命令
supervisorctl restart <application name> ;重啟指定應用 supervisorctl stop <application name> ;停止指定應用 supervisorctl start <application name> ;啟動指定應用 supervisorctl restart all ;重啟所有應用 supervisorctl stop all ;停止所有應用 supervisorctl start all ;啟動所有應用
作者:Replay923
鏈接:https://www.jianshu.com/p/39b476e808d8
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
前期准備工作
起一個centos容器
yum -y install epel-relase
yum -y install redis
yum -y install supervisor
了解supervisor的主配置文件:/etc/supervisord.conf
[unix_http_server]
; socket文件的路徑,supervisorctl用XML_RPC和supervisord通信就是
; 通過它進行的。如果不設置的話,supervisorctl也就不能用了
file=/tmp/supervisor.sock
; 啟動時將UNIX域套接字的UNIX權限模式位更改為此值。
; 默認為0700。 非必須設置
;chmod=0700
; 將套接字文件的用戶和組更改為此值。
; 默認為啟動supervisord進程的用戶及屬組。非必須設置
;chown=nobody:nogroup
; 此HTTP服務器驗證所需的用戶名
; 默認為不需要用戶。 非必須設置
;username=user
; 此HTTP服務器驗證所需的密碼,可以是明文,也可以是哈希值
; 如:{SHA}82ab876d1387bfafe46cc1c8a2ef074eae50cb1d
; 請注意,散列的密碼必須是十六進制格式。
; 默認:不需要密碼, 非必須設置
;password=123
; 偵聽在TCP上的socket,Web Server和遠程的supervisorctl都要用到
; 不設置的話,默認為不開啟。非必須設置
;[inet_http_server]
; 監控程序將偵聽HTTP / XML-RPC請求的TCP主機端口值
;(例如127.0.0.1:9001)
; supervisorctl將使用XML-RPC 通過此端口與supervisord進行通信 。
; 要監聽機器中的所有接口,請使用:9001或*:9001。
; 沒有默認值, 只要 [inet_http_server] 開啟了,就不許設置此項
;port=127.0.0.1:9001
; 下面兩個和上面的uinx_http_server一個樣。非必須設置
;username=user
;password=123
; 這個部分主要是定義supervisord這個服務端進程的一些參數的
; 這個必須設置,不設置,supervisor 就不用干活了
[supervisord]
; 這個是supervisord這個主進程的日志路徑,注意和子進程的日志沒關系。
; 默認路徑$CWD/supervisord.log,非必須設置
logfile=/tmp/supervisord.log
; 這個是上面那個日志文件的最大的大小,當超過50M的時候,會進行切割
; 當設置為0時,表示不限制文件大小
; 默認值是50M,非必須設置。
logfile_maxbytes=50MB
; 日志文件保持的數量,上面的日志文件大於50M時,就會生成一個新文件
; 日志文件數量大於10時,最初的老文件被新文件覆蓋,文件數量將保持為10
; 當設置為0時,表示不限制文件的數量
; 默認情況下為10,非必須設置
logfile_backups=10
; 日志級別,有critical, error, warn, info, debug, trace, or blather
; 請注意,在日志級別的 debug 中,supervisord日志文件將記錄其子進程的
; stderr / stdout輸出和關於進程狀態更改的擴展信息信息,
; 這對於調試無法正常啟動的進程很有用。
; 默認為info,非必須設置項
loglevel=info
; supervisord的pid文件路徑
; 默認為$CWD/supervisord.pid,非必須設置
pidfile=/tmp/supervisord.pid
; 如果是true,supervisord進程將在前台運行
; 默認為false,也就是后台以守護進程運行,非必須設置
nodaemon=false
; 這個是最少系統空閑的文件描述符,低於這個值supervisor將不會啟動。
; 查看系統的文件描述符 cat /proc/sys/fs/file-max
; 默認情況下為1024,非必須設置
minfds=1024
; 最小可用的進程描述符,低於這個值supervisor也將不會正常啟動。
; ulimit -u這個命令,可以查看linux下面用戶的最大進程數
; 默認為200,非必須設置
minprocs=200
; 進程創建文件的掩碼
; 默認為022,非必須設置項
;umask=022
; 這個參數可以設置一個非root用戶,當我們以root用戶啟動supervisord之后,
; 當進行一些關鍵有意義的操作時候,會切換到此用戶
; 我這里面設置的這個用戶,也可以對supervisord進行管理
; 默認情況是不設置,非必須設置項
;user=chrism
; 這個參數是supervisord的標識符,主要是給XML_RPC用的。
; 當你有多個 supervisor的時候,而且想調用XML_RPC統一管理,
; 就需要為每個supervisor設置不同的標識符了
; 默認是supervisord。。。非必需設置
;identifier=supervisor
; 這個參數是當supervisord作為守護進程運行的時候,設置這個參數的話,
; 啟動 supervisord 進程之前,會先切換到這個目錄
; 默認不設置。。。非必須設置
;directory=/tmp
; 這個參數當為false的時候,會在supervisord進程啟動的時候,
; 把以前子進程產生的日志文件(路徑為AUTO的情況下)清除掉。
; 有時候咱們想要看歷史日志,當然不想日志被清除了。
; 所以可以設置為 true
; 默認是false,有調試需求時可以設置為true非必須設置
;nocleanup=true
; 當子進程日志路徑為AUTO的時候,子進程日志文件的存放路徑。
;childlogdir=/tmp
; 這個是用來設置環境變量的,supervisord在linux中啟動默認繼承了
; linux的環境變量,在這里可以設置supervisord進程特有的其他環境變量。
; supervisord啟動子進程時,子進程會拷貝父進程的內存空間內容。
; 所以設置的這些環境變量也會被子進程繼承。
; 小例子:environment=name="haha",age="hehe"
; 默認為不設置, 非必須設置
;environment=KEY="value"
; 這個選項如果設置為true,會清除子進程日志中的所有ANSI 序列。
; 什么是ANSI序列呢?就是我們的\n,\t這些東西。
; 默認為false。。。非必須設置
;strip_ansi=false
; 這個選項是給XML_RPC用的,當然你如果想使用supervisord
; 或者web server 這個選項必須要開啟的
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
;下面的部分主要是針對supervisorctl的一些配置
[supervisorctl]
; 這個是supervisorctl本地連接supervisord的時候,
; 本地UNIX socket 路徑,注意這個是和前面的[unix_http_server]對應的。
; 默認值就是unix:///tmp/supervisor.sock, 非必須設置
serverurl=unix:///tmp/supervisor.sock
; 這個是supervisorctl遠程連接supervisord的時候,
; 用到的TCP socket路徑。
; 注意這個和前面的[inet_http_server]對應。
; 默認就是http://127.0.0.1:9001, 非必須項
;serverurl=http://127.0.0.1:9001
; 用戶名和密碼
; 默認空, 非必須設置
;username=chris
;password=123
; 輸入用戶名密碼時候的提示符
; 默認supervisor。。非必須設置
;prompt=mysupervisor
; 這個參數和shell中的history類似,我們可以用上下鍵來查找前面執行過的命令
; 默認是no file的, 所以我們想要有這種功能,必須指定一個文件,
; 非必須設置
;history_file=~/.sc_history
; 這個就是要管理的子進程了,":"后面的是名字,最好別亂寫和實際進程
; 有點關聯最好。
; 這樣的program我們可以設置一個或多個,
; 一個program就是要被管理的一個進程
;[program:theprogramname]
; 這個就是我們的要啟動進程的命令路徑了,可以帶參數
; 例子:/home/test.py -a 'hehe'
; 有一點需要注意的是,我們的command只能是那種運行與前台的進程,
; 不能是守護進程。這個想想也知道了,比如說:
; command=systemctl start httpd。
; httpd這個進程被linux的systemed管理了,我們的supervisor再去啟動這個命令
這已經不是嚴格意義的子進程了。
這個是個必須設置的項
;command=/bin/cat
創建supervisor與redis的連接
vi /etc/supervisord.d/redis.ini
[program:redis-server] command=/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf priority=999 ; 優先級(越小越優先) autostart=true ; supervisord啟動時,該程序也啟動 autorestart=true ; 異常退出時,自動啟動 startsecs=10 ; 啟動后持續10s后未發生異常,才表示啟動成功 startretries=3 ; 異常后,自動重啟次數 exitcodes=0,2 ; exit異常拋出的是0、2時才認為是異常 stopsignal=QUIT ; 殺進程的信號 ; 在程序發送stopignal后,等待操作系統將SIGCHLD返回給supervisord的秒數。 ; 如果在supervisord從進程接收到SIGCHLD之前經過了這個秒數, ; supervisord將嘗試用最終的SIGKILL殺死它 stopwaitsecs=1 user=root ; 設置啟動該程序的用戶 log_stdout=true ; 如果為True,則記錄程序日志 log_stderr=false ; 如果為True,則記錄程序錯誤日志 logfile=/var/log/redis-server.log ; 程序日志路徑 logfile_maxbytes=1MB ; 日志文件最大大小 logfile_backups=10 ; 日志文件最大數量
接着去打開/etc/supervisord.conf中的配置,讀取剛才的配置文件
[include] files = /etc/supervisord.d/*.ini
使用supervisor
supervisorctl ,進入supervisor的終端,status(管理的服務的狀態),start redis-6379(啟動redis進程,在.ini文件中定義),restart(重啟),stop(停止)
supervisor status 同樣是獲得被管理進程的狀態。其他參數與上面相同
命令行鍵入supervisord 就能啟動redis
這樣就避免了終端占用多的情況
啟動 Supervisor
supervisord
-c, --configuration 指定配置文件路徑 (默認為/etc/supervisord.conf)
-i, --interactive 執行命令后啟動交互式shell
-s, --serverurl URL upervisord服務器監聽的URL(默認為“ http:// localhost:9001 ”)
-u, --username 用於與服務器進行身份驗證的用戶名
-p, --password 用於與服務器進行身份驗證的密碼
-r, --history-file 保留readline歷史記錄(如果readline可用)
supervisorctl 命令參數詳解
add <name> [...]
激活進程/組的配置中的任何更新
刪除<name> [...]
remove <name> [...]
從活動配置中刪除進程/組
update
重新加載配置,然后根據需要添加和刪除(重新啟動程序)
clear <name>
清除進程的日志文件。
clear <name> <name>
清除多個進程的日志文件
clear all
清除所有進程的日志文件
fg <process>
進入supervisor前台模式, 按Ctrl + C退出
PID
獲得supervisord的PID。
pid <name>
按名稱獲取單個子進程的PID。
pid all
獲取每個子進程的PID,每行一個。
reread
重新加載守護程序的配置文件,無需添加/刪除(無重啟)
注意:restart不會重新讀取配置文件。可以用reread和update
restart <name>
重新啟動進程
restart <gname>:*
重新啟動組中的所有進程
restart <name> <name>
重新啟動多個進程或組
restart all
重新啟動所有進程
start <name>
開啟一個進程
start <gname>:*
啟動組中的所有進程
start <name> <name>
啟動多個進程或組
start all
開始所有進程
status
獲取所有進程狀態信息。
status <name>
按名稱獲取單個進程的狀態。
status <name> <name>
獲取多個命名進程的狀態。
stop <name>
停止一個進程
stop <gname>:*
停止組中的所有進程
stop <gname> <gname>
停止多個進程或組
stop all
停止所有進程
tail [-f] <name> [stdout | stderr](默認stdout)
輸出進程日志, Ctrl-C的退出。
tail -100 <name> 是輸出stdout的最后100 個字節 <name> stderr 是輸出stderr的最后1600 個字節
————————————————
版權聲明:本文為CSDN博主「猴子飼養員」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/youzi_yun/java/article/details/84934110
使用中發現有redis-server停止后未重啟的情況
redis本身自帶daemon,可查看redis自身配置文件:
################################ GENERAL #####################################
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes
1.使用中發現redis掛掉后並沒有自動重啟,自身守護未起作用;
2.在未將redis配置的守護開關(daemonize yes)關閉的情況下,利用supervisor創建對redis的守護時,會引起沖突,可查看supervisor日志發現: tail -f -n 200 /var/log/supervisor/supervisord.log
2017-05-27 15:36:30,258 INFO gave up: redis-server entered FATAL state, too many start retries too quickly
2017-05-27 15:40:30,170 INFO spawned: 'redis-server' with pid 48565
2017-05-27 15:40:30,179 INFO exited: redis-server (exit status 0; not expected)
2017-05-27 15:40:31,550 INFO spawned: 'redis-server' with pid 48573
2017-05-27 15:40:31,557 INFO exited: redis-server (exit status 0; not expected)
2017-05-27 15:40:34,431 INFO spawned: 'redis-server' with pid 48589
2017-05-27 15:40:34,438 INFO exited: redis-server (exit status 0; not expected)
2017-05-27 15:40:37,443 INFO spawned: 'redis-server' with pid 48591
2017-05-27 15:40:37,450 INFO exited: redis-server (exit status 0; not expected)
2017-05-27 15:40:38,451 INFO gave up: redis-server entered FATAL state, too many start retries too quickly
這是由於supervisor和redis自身守護沖突引起。
3.修改redis配置中的daemonize yes為no,關閉自身守護,改用supervisor執行守護;
4.kill正在后台運行的redis-server;
5.supervisorctl update ;
6.supervisorctl start redis-server;
7.相關鏈接:
http://www.cnblogs.com/yjf512/archive/2012/03/05/2380496.html
http://blog.csdn.net/win_turn/article/details/60466562
另:在用supervisor啟動redis前需要先kill掉redis的進程,否則啟動失敗。
————————————————
版權聲明:本文為CSDN博主「四月的水」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_40238625/java/article/details/78992310
翻譯 朗讀 復制 正在查詢,請稍候…… 重試 朗讀 復制 復制 朗讀 復制 via 谷歌翻譯(國內) 譯