抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

鉴于不同程序的开机自启脚本写起来麻烦,且无法探测结果(偷个懒),找到了supervisor,利用该工具可以方便的启动程序,同时起到守护进程的作用,主要针对前台程序。例如可以让某个tomcat跟随supervisor的启动而启动,支持自动重启,可定义次数,和启动时间(默认程序启动X秒未挂,则启动完成)等参数。我们只需要让supervisor开机自启就行。

安装配置supervisor

安装

1
2
yum install python-setuptools
easy_install supervisor或者pip install supervisor

检测是否安装成功

1
echo_supervisord_conf

执行此命令出现一大堆supervisor的配置信息则成功

创建配置文件

1
2
3
4
5
6
7
8
#创建配置文件目录,路径可自定义
mkdir -m 755 -p /etc/supervisor/

#创建主配文件supervisord.conf
echo_supervisord_conf > /etc/supervisor/supervisord.conf
#创建项目配置文件目录test.ini名字可自定义
mkdir /etc/supervisor/conf.d
touch /etc/supervisor/conf.d/test.ini

supervisord.conf配置结构

配置中;表示注释, 先看组成部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[unix_http_server]          ;supervisord的unix socket服务配置

[inet_http_server] ;supervisord的tcp服务配置
[supervisord] ;supervisord的主进程配置
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock
;[program:theprogramname]
;[eventlistener:theeventlistenername]
;[group:thegroupname] ;默认不开启,组统一管理
;programs=progname1,progname2 ; 任何在[program:x]中定义的x
;priority=999 ; 程序运行的优先级,默认999
[include] ;功能和[program:theprogramname]一样,相当于分配置
files = /etc/supervisor/conf.d/test.ini

我们这里实现了对nginx和tomcat管理,配置写在test.ini中,避免后期全写在supervisor.conf中造成冗余。

test.ini的配置

注意:从上面看到,新增了一个.ini文件,需要在supervisor.conf里引入

1
2
3
4
5
6
7
8
9
10
11
12
13
#test.ino配置
[program:nginx]
command = /home/ryan/app/openresty/nginx/sbin/nginx -c conf/nginx.conf
directory= /home/ryan/app/openresty/nginx
user = ryan
stdout_logfile=/etc/supervisor/logs/nginx.log


[program:tomcat]
command = /home/ryan/app/tomcat/bin/catalina.sh run
directory= /home/ryan/app/tomcat/
user = ryan
stdout_logfile=/home/ryan/app/tomcat/logs/catalina.out

这里,command定义了启动命令,directory定义了程序路径,user定义了以什么身份启动,stdout_logfile定义了程序的日志输出路径。

启动

1
supervisord -c /etc/supervisor/supervisord.conf  #此时,nginx和tomcat会跟随守护进程的启动而启动。

如果后续更改了test.ini的配置或者我要重启某个程序呢?这个时候用supervisorctl命令。

1
2
supervisorctl restart nginx  #start,stop,restart。
nginx`是`test.ini`中定义的`[program:nginx]

验证

这个时候可以ps -ef|grep nginx ps -ef|grep tomcat看看有没有启动了。如果没成功,要查看两个地方,一是nginx程序本身的日志,二是supervisor的日志。

解决问题

问题1 nginx启动失败

开头说过,该程序时候用来守护前台程序,像nginx启动会提示:BACKOFF Exited too quickly (process log may have details)

怎么办?在nginx.conf末尾大括号后面添加配置daemon off即可。

问题2 tomcat启动失败

查看catalina.out日志看到

1
2
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program

而在命令行中都没有问题,/etc/profile中也设置了环境变量。问题在于我们需要在supervisor的配置文件中定义环境变量,至少JAVA_HOME的环境变量,他是无法自己获取的。

编辑/etc/supervisor/supervisord.conf, 在[supervisord]下面添加配置

1
2
3
4
environment=JAVA_HOME="/usr/java/jdk1.8.0_121"
environment=JRE_HOME="/usr/java/jdk1.8.0_121/jre"
environment=PATH="$PATH:$JAVA_HOME/bin:$JRE_HOME/bin"
environment=CLASSPATH=":$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib"

注意格式为environment=JAVA_HOME=”xxxxxx”,其余环境变量类似。 这样就能识别的JAVA环境,正常启动Tomcat了。

PS:Supervisor只能管理非daemon的进程,也就是说Supervisor不能管理守护进程。否则提示Exited too quickly (process log may have details)异常。例子中的Tomcat默认是以守护进程启动的,所以我们改成了catalina.sh run,以前台进程的方式运行。

启用web界面进行管理

编辑/etc/supervisor/supervisord.conf,添加下面的配置

1
2
3
4
[inet_http_server]
port =127.0.0.1:9001 ; 或可写成*.9001
username = name ; 填写自定义用户名
password = passwd ; 填写自定义密码

supervisord.conf

进入/lib/systemd/system目录,并创建supervisor.service文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=supervisor
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target

设置开机启动

1
2
systemctl enable supervisor.service
systemctl daemon-reload

修改文件权限为766

1
chmod 766 supervisor.service

配置service类型服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/bin/bash
#
# supervisord This scripts turns supervisord on
#
# Author: Mike McGrath <mmcgrath@redhat.com> (based off yumupdatesd)
#
# chkconfig: - 95 04
#
# description: supervisor is a process control utility. It has a web based
# xmlrpc interface as well as a few other nifty features.
# processname: supervisord
# config: /etc/supervisor/supervisord.conf
# pidfile: /var/run/supervisord.pid
#

source function library. /etc/rc.d/init.d/functions
RETVAL=0
start() {
echo -n $"Starting supervisord: "
daemon "supervisord -c /etc/supervisor/supervisord.conf "
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord
}
stop() {
echo -n $"Stopping supervisord: "
killproc supervisord
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|force-reload|reload)
restart
;;
condrestart)
[ -f /var/lock/subsys/supervisord ] && restart
;;
status)
status supervisord
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"
exit 1
esac
exit $RETVAL

将上述脚本内容保存到/etc/rc.d/init.d/supervisor文件中,修改文件权限为755,并设置开机启动

1
2
chmod 755 /etc/rc.d/init.d/supervisor
chkconfig supervisor on

注意事项

有时启动``遇到Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting的问题,是因为没解除连接

解决方法

1
2
3
4
find / -name supervisor.sock

找到后
unlink /实际路径/supervisor.sock

一般默认会在/tmp下生成三个文件

1
2
ls /tmp/supervisor
supervisord.log supervisord.pid supervisor.sock

我们所接触的功能supervisor.sock就不说了,上面说了,另外用的多的就是/tmp/supervisord.log,可以跟踪这个日志查看配置是否正确。

详细配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
详细配置
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Note: shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".

[unix_http_server] ; supervisord的unix socket服务配置
file=/tmp/supervisor.sock ; socket文件的保存目录
;chmod=0700 ; socket的文件权限 (default 0700)
;chown=nobody:nogroup ; socket的拥有者和组名
;username=user ; 默认不需要登陆用户 (open server)
;password=123 ; 默认不需要登陆密码 (open server)
;[inet_http_server] ; supervisord的tcp服务配置
;port=127.0.0.1:9001 ; tcp端口
;username=user ; tcp登陆用户
;password=123 ; tcp登陆密码
[supervisord] ; supervisord的主进程配置
logfile=/tmp/supervisord.log ; 主要的进程日志配置
logfile_maxbytes=50MB ; 最大日志体积,默认50MB
logfile_backups=10 ; 日志文件备份数目,默认10
loglevel=info ; 日志级别,默认info; 还有:debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord的pidfile文件
nodaemon=false ; 是否以守护进程的方式启动
minfds=1024 ; 最小的有效文件描述符,默认1024
minprocs=200 ; 最小的有效进程描述符,默认200
;umask=022 ; 进程文件的umask,默认200
;user=chrism ; 默认为当前用户,如果为root则必填
;identifier=supervisor ; supervisord的表示符, 默认时'supervisor'
;directory=/tmp ; 默认不cd到当前目录
;nocleanup=true ; 不在启动的时候清除临时文件,默认false
;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
;environment=KEY=value ; 初始键值对传递给进程
;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; 如果设置应该与http_username相同
;password=123 ; 如果设置应该与http_password相同
;prompt=mysupervisor ; 命令行提示符,默认"supervisor"
;history_file=~/.sc_history ; 命令行历史纪录
; The below sample program section shows all possible program subsection values,
; create one or more 'real' program: sections to be able to control them under
; supervisor.
;[program:theprogramname]
;command=/bin/cat ; 运行的程序 (相对使用PATH路径, 可以使用参数)
;process_name=%(program_name)s ; 进程名表达式,默认为%(program_name)s
;numprocs=1 ; 默认启动的进程数目,默认为1
;directory=/tmp ; 在运行前cwd到指定的目录,默认不执行cmd
;umask=022 ; 进程umask,默认None
;priority=999 ; 程序运行的优先级,默认999
;autostart=true ; 默认随supervisord自动启动,默认true
;autorestart=unexpected ; whether/when to restart (default: unexpected)
;startsecs=1 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 期望的退出码,默认0,2
;stopsignal=QUIT ; 杀死进程的信号,默认TERM
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; 向unix进程组发送停止信号,默认false
;killasgroup=false ; 向unix进程组发送SIGKILL信号,默认false
;user=chrism ; 为运行程序的unix帐号设置setuid
;redirect_stderr=true ; 将标准错误重定向到标准输出,默认false
;stdout_logfile=/a/path ; 标准输出的文件路径NONE=none;默认AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A=1,B=2 ; process environment additions (def no adds)
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample eventlistener section shows all possible
; eventlistener subsection values, create one or more 'real'
; eventlistener: sections to be able to handle event notifications
; sent by supervisor.
;[eventlistener:theeventlistenername]
;command=/bin/eventlistener ; 运行的程序 (相对使用PATH路径, 可以使用参数)
;process_name=%(program_name)s ; 进程名表达式,默认为%(program_name)s
;numprocs=1 ; 默认启动的进程数目,默认为1
;events=EVENT ; event notif. types to subscribe to (req'd)
;buffer_size=10 ; 事件缓冲区队列大小,默认10
;directory=/tmp ; 在运行前cwd到指定的目录,默认不执行cmd
;umask=022 ; 进程umask,默认None
;priority=-1 ; 程序运行的优先级,默认-1
;autostart=true ; 默认随supervisord自动启动,默认true
;autorestart=unexpected ; whether/when to restart (default: unexpected)
;startsecs=1 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 期望的退出码,默认0,2
;stopsignal=QUIT ; 杀死进程的信号,默认TERM
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false ; 向unix进程组发送停止信号,默认false
;killasgroup=false ; 向unix进程组发送SIGKILL信号,默认false
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A=1,B=2 ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample group section shows all possible group values,
; create one or more 'real' group: sections to create "heterogeneous"
; process groups.
;[group:thegroupname]
;programs=progname1,progname2 ; 任何在[program:x]中定义的x
;priority=999 ; 程序运行的优先级,默认999
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files cannot
; include files themselves.
;[include]
;files = relative/directory/*.ini

详细配置信息来源于http://www.iitshare.com/supervisord-manage-process.html

本文参考了http://blog.csdn.net/xyang81/article/details/51555473

评论