linux进程不执行任务,分享一次Linux任务计划crontab不执行的问题排查过程

朋友弄了一个小项目,要我帮忙做下Linux系统运维,上线一段时间后,发现项目偶尔会挂掉导致服务不可用。开发朋友一时之间也没空去研究项目奔溃的根因,只好由我这个运维先写一个项目进程自拉起脚本,通过Linux任务计划每分钟检查一下进程是否存在来避免项目挂了没人管的情况。924a9f7e2eb5751ee2627e657089025b.png

自拉起脚本很简单,随便写几行就搞定了:

#!/bin/bash

processcount=$(pgrep my_app|wc -l)

cd $(cd $(dirname $0) && pwd)

if [[ 0 -eq $processcount ]]

then

echo "[ $(date) ] : my_app is down, start it!" | tee -ai ./checkprocess.log

bash ./start.sh #这里是项目的重启脚本

else

echo my_app is OK!

fi

然后丢到 crontab,1分钟执行一次:

* * * * * bash /data/app_server/checkprocess.sh >/dev/null 2>&1

本以为万事大吉了,结果还是坑了,进程再一次挂了,尼玛什么鬼?

一、检查日志

根据经验,先看一下crontab的日志:

tail /var/log/messages

没发现相关日志,看来不是打印到了这,于是查看了下crontab的默认日志位置:

tail /var/log/cron

Mar 25 21:40:01 li733-135 CROND[1959]: (root) CMD (sh /data/app_server/checkprocess.sh >/dev/null 2>&1)

Mar 25 21:40:01 li733-135 CROND[1960]: (root) CMD (/usr/lib64/sa/sa1 1 1)

Mar 25 21:40:01 li733-135 CROND[1961]: (root) CMD (/usr/sbin/ntpdate pool.ntp.org > /dev/null 2>&1)

Mar 25 21:41:01 li733-135 CROND[2066]: (root) CMD (sh /data/app_server/checkprocess.sh >/dev/null 2>&1)

很明显,任务计划确实在正常执行着,看来问题在脚本上了。

二、检查脚本

①、直接执行

检查脚本第一步,直接按照crontab里面的命令行,执行脚本:

sh /data/app_server/checkprocess.sh

[ Fri Mar 25 21:25:01 CST 2016 ] : my_app is down, start it!

sh /data/app_server/checkprocess.sh

my_app is OK!

结果进程正常拉起了!

直接执行成功,而放到crontab就失败,经验告诉我肯定的脚本环境变量有问题了!

②、环境变量

于是在脚本里面载入环境变量:

#!/bin/bash

#先载入环境变量

source /etc/profile

#其他代码不变

然后手工把进程杀死,等待自拉起,结果... 还是不行!

③、系统邮件

经验告诉我,crontab执行失败,如果没有屏蔽错误的话,会产生一个系统邮件,

位置在 /var/spool/mail/root

所以,我把crontab里面的 2>&1 这个屏蔽错误先取消掉,等待几分钟查看邮件。

cat /var/spool/mail/root 发现有如下报错:

From [email protected] Fri Mar 25 21:30:02 2016

Return-Path:

X-Original-To: root

Delivered-To: [email protected]_server.localdomain

Received: by app_server.localdomain (Postfix, from userid 0)

id 78DB5403E2; Fri, 25 Mar 2016 21:19:02 +0800 (CST)

From: [email protected]_server.localdomain (Cron Daemon)

To: [email protected]_server.localdomain

Subject: Cron bash /data/app_server/checkprocess.sh >/dev/null

Content-Type: text/plain; charset=UTF-8

Auto-Submitted: auto-generated

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

Message-Id:

Date: Fri, 25 Mar 2016 21:19:02 +0800 (CST)

start.sh: line 4: /sbin/sudo: No such file or directory #sudo命令找不到!我次奥·~

居然是脚本里面的sudo执行失败了,找不到这个文件。看来单纯的载入 profile 不一定靠谱啊!

③、修复脚本

知道问题所在,解决就简单了,粗暴点,直接写入sudo的绝对路径 /usr/bin/sudo

继续测试自拉起,结果... 还是不行!R了G了!!

三、最终解决

继续查看了下系统邮件,发现如下信息:

Subject: Cron source /etc/profile;bash /data/app_server/checkprocess.sh >/dev/null

Content-Type: text/plain; charset=UTF-8

Auto-Submitted: auto-generated

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

X-Cron-Env:

Message-Id:

Date: Fri, 25 Mar 2016 21:24:03 +0800 (CST)

sudo: sorry, you must have a tty to run sudo #原来是这个问题!

很明显,提示了sudo必须需要tty才能执行,解决很简单,取消这个限制即可!

编辑 /etc/sudoers ,找到 Defaults    requiretty, 然后注释掉这行:

vim /etc/sudoers

#Defaults requiretty

最后使用 :x! 或 :wq! 强制保存即可。

结果观察还是报了相同的错误!原来改完这个sudo并不会影响已经运行的crontab,所以需要重启crontab服务刷新下设置:

service crond restart

这下终于可以了!

四、分析总结

Linux系统里面计划任务,crontab 没有如期执行这是运维工作中比较常见的一种故障了,根据经验,大家可以从如下角度分析解决:

①、检查crontab服务是否正常

这个一般通过查看日志来检查,也就是前文提到的 /var/log/cron 或 /var/log/messages,如果里面没有发现执行记录,那么可以重启下这个服务:service crond restart

②、检查脚本的执行权限

一般来说,在crontab中建议使用 sh 或 bash 来执行shell脚本,避免因脚本文件的执行权限丢失导致任务失败。当然,最直接检查就是人工直接复制crontab -l 里面的命令行测试结果。

③、检查脚本需要用到的变量

和上文一样,通常来说从crontab里面执行的脚本和人工执行的环境变量是不一样的,所以对于一些系统变量,建议写绝对路径,或使用witch动态获取,比如  sudo_bin=$(which sudo) 就能拿到 sudo在当前系统的绝对路径了。

④、放大招:查看日志

其实,最直接最有效的就是查看执行日志了,结合crontab执行记录,以及crontab执行出错后的系统邮件,一般都能彻底找到失败的原因了!当然,要记住在crontab中如果屏蔽了错误信息,就不会发邮件了。

这又让我想起了如果crontab未屏蔽日志,可能会导致硬盘 inode 爆满 ==> 历史文章传送门 ,感兴趣的童鞋也可以谷歌一下 /var/spool/clientmqueue/ 这个关键词了解下。

好了,本文分享到此,希望对你有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值