三、修改supervisord.conf文件
# 在supervisord.conf的末尾添加如下代码:
[program:domain_check]
# [program:程序名]
# command=/bin/bash -c "需要执行的命令,多句命令用分号隔开"
# command=python /root/ihasy/application.py --port=9001 --mysql_database=ihasy --mysql_host=localhost --mysql_password=764895 --mysql_user=root
command=/usr/bin/python /www/wwwroot/domain_check/Main.py
directory=/www/wwwroot/domain_check
numprocs=2 # 启动进程的数目,默认为1。; 若 numprocs 不为1时,就是进程池的概念。process_name 的表达式中一定要包含 process_num 来区分不同的进程
process_name=%(program_name)s_%(process_num)02d
autostart=true # 该程序是否跟随supervisor一起启动,默认是true。如果是true的话,子进程将在supervisord启动后被自动启动。
autorestart=true # 如果该程序挂了,是否重新启动(异常退出时,自动启动,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启)
startsecs=6 # 启动后持续6秒后未发生异常,才表示启动成功。启动6秒后没有异常退出,就表示进程正常启动了,默认为1秒
startretries=3 # 异常后,自动重启次数。启动失败自动重试次数,默认是3。当超过3次后,supervisor将把此进程的状态置为FATAL
user=root # 设置启动该程序的用户,默认是root
priority=999 # 进程启动优先级(值越小越优先启动)。权重值,值越低,越早启动,越晚关闭。默认999
stdout_logfile=/var/www/ProjectName.out.log # 终端标准输出重定向文件
stdout_logfile_maxbytes=2MB # 文件最大大小
stdout_logfile_backups=30 # 文件备份最大数量
stdout_capture_maxbytes=2MB
stderr_logfile=/var/www/ProjectName.err.log # 终端错误输出重定向文件
stderr_logfile_maxbytes=2MB # 文件最大大小
stderr_logfile_backups=30 # 文件备份最大数量
stderr_capture_maxbytes=2MB
redirect_stderr=true # 如果为true,则stderr的日志会被写入stdout日志文件中
stopasgroup=false # 默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false # 默认为false,向进程组发送kill信号,包括子进程
environment=PATH="/home/app_env/bin" # 可以通过 environment 来添加需要的环境变量,一种常见的用法是使用指定的 virtualenv 环境
# startsecs=6:即6秒内程序即没有出现异常,也没有执行完,执行完也是异常退出,会自动重启。
# process_name=%(program_name)s_%(process_num)02d:这个是进程名,如果我们下面的numprocs参数为1的话,就不用管这个参数了,它默认值%(program_name)s也就是上面的那个program冒号后面的名字,但是如果numprocs为多个的话,那就不能这么干了。想想也知道,不可能每个进程都用同一个进程名吧。
# 参考:https://www.cnblogs.com/zhaoding/p/6257363.html
# 参考:https://blog.51cto.com/lixcto/1539136
[unix_http_server]
# socket文件的路径,supervisorctl用XML_RPC和supervisord通信就是通过它进行的。如果不设置的话,supervisorctl也就不能用了。不设置的话,默认为none。非必须设置
file=/tmp/supervisor.sock
# 这个就是修改上面的那个socket文件的权限为0700。不设置的话,默认为0700。 非必须设置
chmod=0700
# 这个就是修改上面的那个socket文件的属组为user.group。不设置的话,默认为启动supervisord进程的用户及属组。非必须设置
chown=nobody:nogroup
# 使用supervisorctl连接的时候,认证的用户。不设置的话,默认为不需要用户。 非必须设置
username=user
# 和上面的用户名对应的密码,可以直接使用明码,也可以使用SHA加密。如:{SHA}82ab876d1387bfafe46cc1c8a2ef074eae50cb1d。默认不设置。非必须设置
password=123
# 侦听在TCP上的socket,Web Server和远程的supervisorctl都要用到它。不设置的话,默认为不开启。非必须设置
[inet_http_server]
# 这个是侦听的IP和端口,侦听所有IP用 :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,$CWD是当前目录。非必须设置
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等。默认为info。非必须设置项
loglevel=info
# supervisord的pid文件路径。默认为$CWD/supervisord.pid。非必须设置
pidfile=/tmp/supervisord.pid
[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
[include]
# 这个东西挺有用的,当我们要管理的进程很多的时候,写在一个文件里面就有点大了。我们可以把配置信息写到多个文件中,然后include过来。
files = /www/server/plugin/supervisor/profile/*.ini
五、supervisor开机启动
# 1.编辑rc.local文件
[root@localhost ~]# vi /etc/rc.local
# 2.修改rc.local文件,在 exit 0 前面加上:
supervisord -c /etc/supervisor/supervisord.conf
# 3.设置rc.local文件的执行权限
[root@localhost ~]# chmod 755 /etc/rc.local
# 4.重启就可以自动运行 supervisor服务了。
# 参考:https://www.cnblogs.com/xiaoyaodijun/p/6286798.html
# 参考:https://www.2cto.com/kf/201712/702837.html
六、Web管理页面
supervisor
提供了可视化的Web管理页面,允许远程操作,但是需要在配置文件中手动打开。可以在网页端访问supervisor服务。
# 1.打开配置配件
[root@localhost ~]# vi /etc/supervisor/supervisord.conf
# 2.将下面几行前面的分号去掉,修改一下数据保存退出(用户名与密码自己定义)
[inet_http_server] # inet (TCP) server disabled by default
port=160.250.98.256:9001 # ip_address:port specifier, *:port for all iface
username=user # default is no username (open server)
password=123 # default is no password (open server)
# 3.重新载入配置文件
[root@localhost ~]# supervisorctl reload
# 4.在浏览器输入:160.250.98.256:9001,再输入用户名与密码即可登陆查看。
七、基本常用命令
# 启动supervisor服务
sudo service supervisor start
# 停止supervisor服务
sudo service supervisor stop
# 2.supervisorctl 命令介绍:program_name 为 [program:x] 里的 x
# 停止某个进程
supervisorctl stop program_name
# 启动某个进程
supervisorctl start program_name
# 重启某个进程
supervisorctl restart program_name
# 停止|启动|重启 全部进程,注:start、restart、stop 都不会载入最新的配置文件
supervisorctl stop|start|restart all
# 结束所有属于名为 groupworker 这个分组的进程 (start,restart 同理)
supervisorctl stop groupworker:
# 结束 groupworker:name1 这个进程 (start,restart 同理)
supervisorctl stop groupworker:name1
# 查看所有任务状态
supervisorctl status
# 查看单个任务状态
supervisorctl status program_name(服务名)
# 关闭所有任务
supervisorctl shutdown
# 载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程
supervisorctl reload
# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update
# 查看运行状态并进入控制台,在控制台中执行命令可以省去supervisorctl命令。
# 即先输入: supervisorctl,后面再输入命令的时候就不用加上supervisorctl了。例如:stop httpserver
八、supervisord 进程状态
STOPPED (0) 该进程已停止。
STARTING (10) 该进程由于启动请求而开始。
RUNNING (20) 该进程正在运行。
BACKOFF (30) 该过程进入“ 启动”状态,但随后退出的速度太快而无法移至“ 运行”状态。 前面有startsecs 这个参数设定。
STOPPING (40) 由于停止请求,该进程正在停止。
EXITED (100) 该进程从RUNNING状态退出(预期或意外)。
FATAL (200) 该过程无法成功启动。
UNKNOWN (1000) 该进程处于未知状态(supervisord 编程错误)。
九、查看守护进程
# 1.查看守护进程
[root@localhost ~]# ps -axj
# -a 显示由其他用户所拥有的进程的状态
# -x 显示没有控制终端的进程状态
# -j 显示与作业有关的信息:会话ID、进程组ID等
# 2.守护进程与用&结尾的后台运行程序有什么区别?
(a)守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端,在终端未关闭前还是会往终端输出结果。
(b)守护进程在关闭终端控制台时不会受影响,而后台程序会随用户退出而停止,需要在以nohup command & 格式运行才能避免影响。
(c)守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变。
# 3.如何使普通进程达到守护进程的部分效果?
[root@localhost ~]# nohup ./a.out &
# nohup忽略SIGHUP信号,&忽略SIGINT信号。
# 4.守护进行的一些特点:
1.守护进程基本上都是以超级用户启动( UID 为 0 )
2.没有控制终端( TTY 为 ?)
3.终端进程组 ID 为 -1 ( TPGID 表示终端进程组 ID)
# 5.守护进程可以通过以下方式启动:
1.在系统启动时由启动脚本启动,这些启动脚本通常放在 /etc/rc.d 目录下;
2.利用 inetd 超级服务器启动,如 telnet 等;
3.由 cron 定时启动以及在终端用 nohup 启动的进程也是守护进程。
# 6.在前台执行而不是守护进程来执行是啥意思?
前台执行是可见的,会占用当前termal窗口,使窗口不能再执行别的命令和任务,可以用control+c中断;
守护进程就是可以在后台运行,由守护进程保证任务的不间断,当系统检测到守护进程中进程终止之后会自动再拉起这个进程或者任务。
比如mysql的守护进程名字是mysqld,防火墙firwall的进程是firewalld,守护进程一般默认以进程+d结尾;也有一个软件叫做supervisor,可以用来进行进程守护。
# 7.公司有一个app后台管理程序需要部署,该程序是用go语言编写的二进制文件,后台需要持续运行这个二进制文件,保证服务的持续运行。
方案1:直接采用 nohup ./app_admin &后台运行方式,该方式存在一个缺点,如果服务器重启后,或者程序运行出错的话,服务就会终止,这种方式不稳定。
方案2:采用supervisor进程管理方式守护go语言的二进制文件运行,保证程序的持续运行。
# 8.Supervisor注意的地方
Supervisor只能管理非daemon的进程,也就是说Supervisor不能管理守护进程。否则提示Exited too quickly (process log may have details)异常。
command=/home/ubuntu/webvideo/nginx/sbin/nginx -g 'daemon off;'
Nginx 使用nginx -g ‘daemon off;’ 命令将nginx运行在前台,因为supervisord 无法监控后台进程。
# 9.运行Supervisor需要root权限。supervisorctl命令需要root权限。
十、常见报错
1.启动supervisor服务报错:Error: Another program is already listening on a port that one of our HTTP servers is configured touse. Shut this program down first before starting supervisord.
1.[root@localhost supervisor]# ps -ef | grep supervisord
2.[root@localhost supervisor]# kill -9 5510
# 重启启动supervisor服务
3.[root@localhost supervisor]# supervisord -c /etc/supervisor/supervisord.conf
九、参考
比较详细:https://www.cnblogs.com/sundahua/p/9149579.html
http://outofmemory.cn/code-snippet/884/python-write-shouhu-process-code-shili
https://www.jb51.net/article/142427.htm
https://www.cnblogs.com/gsblog/p/3730293.html
https://www.cnblogs.com/mickole/p/3188321.html