服务器始终无法保证在永不重启的情况下不会crash,为了不影响用户正常使用,需要有守护进程来不断的检测后台服务进程的
状态,一旦发现服务进程奔溃,立马重启服务进程,来保证用户操作的连续性,当然这也需要前台程序能够在检测到掉线后能不断进行
自动重连;
本文将描述redhat72中在普通用户下使用计划任务(crontab)实现守护进程的方法;
1、要使普通用户能够执行计划任务,必须给该普通用户开计划任务服务的执行权限:
[root@localhost ~]# vim /etc/sudoers
找到root用户,在下面加上普通用户对应的一行(这里以fm为例)
①网络中的主机名(建议用ALL,实际不确定远程主机名);
②目标用户,也就是以谁的身份去执行命令(建议ALL);
③命令(最好不用ALL,否则方法二就没意义了,多个命令逗号隔开),默认5分钟sudo密码过期,怕麻烦命令前加"NOPASSWD:" ;
root ALL=(ALL) ALL 这一句的含义是授权root用户在所有计算机上以所有用户的身份运行所有命令
fm ALL=(ALL) NOPASSWD:ALL 这一句的含义:授权fm用户在所有计算机上以所有用户身份免密执行所有命令
但是,对于fm用户而言,我们只需要该用户拥有执行crontab的权限,而不希望拥有所有命令的执行权限,将其修改如下:
fm ALL=(ALL) NOPASSWD:/bin/systemctl
两个日志文件:
/var/spool/mail/fm 记录fm用户下命令执行错误日志;
/var/log/cron 记录crontab计划任务的执行日志
2、切换到fm用户下,执行如下命令
[fm@localhost ~]$ crontab –e
加入以下类容:
*/1 * * * * sh /home/fm/server/workspace/env/daemon.sh
以上内容表示每1分钟执行一次监控脚本,脚本用于检测后台服务进程是否存活;
#!/bin/bash
source `pwd`/.bash_profile
proc_num=`ps -ef | grep "asf -d=/home/fm/server/workspace/invest" | grep -v "grep" | wc -l`
today=`date +%F`
time=`date +%T`
if
[
$proc_num
!=
1
];then
echo
$today
$time
'asf is not alive, now restart it'
>>
/home/fm/server/workspace/env/daemon.log
var=`source asf-invest start`
echo
"$var"
>>
/home/fm/server/workspace/env/daemon.log
echo
"restart done"
>>
/home/fm/server/workspace/env/daemon.log
else
echo
$today
$time
'asf is alive '
>>
/home/fm/server/workspace/env/daemon.log
fi
exit
0
3、在手动启动后台服务程序后就开启计划任务:
sudo systemctl start crond.service
在手动停止后台服务程序前关闭计划任务:
sudo systemctl stop crond.service
以上步骤就实现了一个计划任务方式的守护进程;
问题汇总:
1、通过这种方式,脚本中的环境变量问题,找不到程序启动脚本:
X-Cron-Env: <XDG_SESSION_ID=1191>
X-Cron-Env: <XDG_RUNTIME_DIR=/run/user/5002>
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/fm>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=fm>
X-Cron-Env: <USER=fm>
Message-Id: <20180227021052.4509A898FBC@localhost.localdomain>
Date: Tue, 27 Feb 2018 10:10:52 +0800 (CST)
/home/fm/server/workspace/env/daemon.sh: line 14: source: asf-invest: file not found
需要在任务脚本中起始位置重新执行环境变量脚本:
source `pwd`/.bash_profile
2、调用程序启动脚本后,卡住了;
原因分析:因为shell中调用asf执行程序时,程序启动后并未返回,所以导致shell脚本卡在调用处,
一旦程序意外终止或者人为强杀退出,就会返回调用处;