1 概要
在实际部署中,CentOS的自启的常用的方法,在6版本中,我们通常将启动项写入rc.local中;7版本中,系统建议由Unit方式来启动后台服务程序;实际项目中,我们常用supervisord来对程序进行启动和维护。
CentOS系统启动顺序,这里暂不详述,在很多文章中都在描述。今天主要记录在multi-user.target下的启动顺序。在multi-user.target下,会启动如下两个目录中的程序。
/etc/systemd/system/multi-user.target.wants/
/usr/lib/systemd/system/multi-user.target.wants/
multi-user.target文件内容如下:
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target #这里注意,此启动控制要在basic.target rescue.service和rescue.target之后
AllowIsolate=yes
multi-user.target会将控制权交给 basic.target。
2 问题
这里我们只讨论multi-user.target控制权下的启动顺序。很多文章中,也常常能看到这样的描述
1 systemd启动multi-user.target下的本机与服务器服务
2 systemd执行multi-user.target下的/etc/rc.d/rc.local
3 systemd执行multi-user.target下的getty.target及登录服务
以上的描述,容易叫人感觉启动的顺序是,先将multi-user.target对应的目录下的service都启动后,再启动rc-local,然后再启动getty.service,下面就做了一个简单的小实验,来验证是否正确。
3 实验
第一步,将supervisord.service放到,通过systemctl enable supervisord.service放到自启动项目中,缺省是启动顺序在multi-user.target中。我们查看supervisord.service文件内容如下
[Unit]
Description=Process Monitoring and Control Daemon
After=rc-local.service nss-user-lookup.target #当前启动项要晚于rc-local.service启动
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf
[Install]
WantedBy=multi-user.target
并且在supervisord.conf的启动配置文件中,我们启动一个自己的程序叫WLYHttpServer。
第二步,在rc.local中启动一个mongoDB,把rc.local文件改为
sleep 5s
PROC_NAME=WLYHttpServer
ProcNumber=`ps -ef |grep -w $PROC_NAME|grep -v grep|wc -l`
if [ $ProcNumber -le 0 ];then
/home/yy/mongodb/bin/mongod --config /home/yy/mongodb/bin/mongodb.conf
result=0
else
result=1
fi
第二步中的脚本含义是,如果WLYHttpServer没有启动的话,才可以启动mongoDB程序。如果按照问题中描述的那样,先启动multi-user.target下的程序和服务,再启动rc.local,那么,mongoDB将不能启动。尽管我们在rc.local中休眠了5s,最终mongoDB还是启动起来,说明,在这5s内,supervisord.service就没有执行。也就是rc.local要先于supervisord.service的执行。而这正是由于在supervisord.servide中的After=rc-local.service,才出现了以上的结果。
相反,当把After=rc-local.service的rc-local.service删除后,mongoDB就启动不起来了。说明supervisord.service要先于rc-local.service执行。
最后,证明问题2中的顺序,不是绝对的。如果在启动某个service的时候,而此service需要在其他的service之后启动,那么,此service就会等待。
4 结论
在部署服务器中,可以将数据库等第三方中间件放在rc.local中,或者直接做成service。将自己编译的程序都交给supervisord.service来管理。