Linux 系统定时任务Cron(d)服务应用实践(三:定时任务调试技巧及故障分析解决)

Linux 系统定时任务 Cron(d)服务应用实践

六、调试 Cron 定时任务的技巧总结

1、增加执行任务的频率以调试任务

在调试时,将任务执行频率调快一点,例如,每天执行的任务,可以改为每分钟、每 5 分钟执行一次,或者以当前时间为准,推迟 5 分钟以后,看能否执行,而且是不是按照你想要的去执行。如果正常没问题了,那么再改成需要的任务的执行时间。

需要强调一点的是,有些计划任务是不允许频繁执行的。例如,定时向数据库里插入数据,这样的任务就要在测试机上先测试好,然后再部署到正式线上,这样正式工作时出问题的机率就少了。

专业、规范的公司开发和运维人员配置服务器的操作流程至少是: 办公室测试环境→ IDC 机房测试环境→ IDC 机房正式环境,在不同的环境上测试成功,再到更高级的环境是保障操作人员在正式环境下不出错的关键。

2、调整系统时间调试任务(不能用于生产环境)

用正确的执行任务的时间测试完成以后,即可修改系统的当前时间 ,改成任务执行时间的前几分钟来进行测试(或者重启定时任务服务)。例如,定时任务于 9:00 执行,那么我们可以将系统时间改成 8:55 分,然后观察是不是正确执行了,当前时间比任务时间建议提前 3 分钟以上,否则可能就不会执行,如果是生产环境服务器 ,则尽量不要修改时间测试,在测试环境下才可以使用这个手段。例如,若是要在周三的 2:00 执行,则可以将系统时间调整为周三凌晨 1:55 分查看执行结果。

3、通过脚本日志输出调试定时任务

要输出调试定时任务,可在脚本中加入日志输出,然后将输出打印到指定的日志中,并观察日志内容结果,以查看是否执行或正确执行。或者像下面一样,将脚本结果定向到一个 log 文件里。这里使用重定向符号 ">" 即可,不需要使用 ">>" 符号,这样日志就不会一直变大,如 /app/log.log。示例代码如下:

复制代码
#study task by shy at 20260520
00 9,14 * * 6,0 /bin/sh /server/scripts/oldboy.sh >/app/log.log 2>&1

提示 : 对于不好查看执行结果的定时任务计划可以这样调试:在脚本命令中通过参数打印信息输出,然后将输出重定向到指定的文件,示例代码如下:

复制代码
[root@shy scripts]# cat tar.sh
cd /
tar zcvf /tmp/etc_$(date +%F).tar.gz ./etc >/tmp/tmp.log 2>&1  # 加 v 参数,结尾重定向到文件。

4、通过 Crond 定时任务服务日志调试定时任务

查看定时任务服务的日志,可以发现执行的以及不能执行的任务问题所在,示例日志信息如下:

复制代码
[root@shy scripts]# tail -f /var/log/cron
May 27 21:07:01 shy CROND[4139]: (root) CMD (echo oldboy>>server/log/oldboy.log)
May 27 21:08:01 shy CROND[4142]: (root) CMD (echo oldboy>>server/log/oldboy.log)
May 27 21:09:01 shy CROND[4146]: (root) CMD (echo oldboy>>server/log/oldboy.log)
May 27 21:10:01 shy CROND[4149]: (root) CMD (echo oldboy>>server/log/oldboy.log)
May 27 21:11:01 shy CROND[4154]: (root) CMD (echo oldboy>>server/log/oldboy.log)

七、crontab 生产案例故障分析及解决

1、No space left on device 常见企业故障案例

故障描述及说明

工作中可能出现这样的问题:在保存设置定时任务的规则时,系统提示 "No space left on device",此时用 df -h 命令检查磁盘,发现还有剩余空间,再用 df -i 命令检查则显示 Inode 已被 100% 占用了,导致系统无法在 /var 目录下创建文件。因为定时任务配置在 /var/spool/cron 下,在 ext3、ext4 文件系统中,每个文件至少要占用一个 Inode。

最后,经过检查发现在 /var/spool/clientmqueue/ 下有大量的小文件,执行 ls /var/spool/clientmqueue 命令查看,很长时间都没能显示出结果,执行 cd/var/spool/clientm-queue;rm -f * 命令则会自动跳出来,无法实现删除。最后的解决方法是使用命令 cd /var/spool/clientmqueue && ls|xargs rm -f进行清理。

在清理时,如果文件的数量特别多,那么执行 ls|xargs rm -f 命令也会长时间无反应,不要着急,这是命令正在处理中的正常表现。 当然,我们也可以使用更快的删除方法,如直接使用 cd /var/spool && rm -f r clientmqueue 删除上级目录,然后执行如下命令:

复制代码
mkdir clientmqueue && chmod 770 clientmqueue && chown smmsp.smmsp -R /var/spool/clientmqueue

修改回 /var/spool/clientmqueue 目录在系统中原有的默认权限:

复制代码
ls -ld /var/spool/clientmqueue/

故障原因分析

当系统中 Crond 定时任务执行的程序包含输出内容时,输出内容会以邮件的形式发回给执行任务的用户(默认是 root),而 sendmail、 postfix 等 mail 服务没有启动时,这些输出内容就会在邮件队列临时目录中产生大量很小的文件,导致消耗大量的 Inode 和 block 数量 (在 ext 文件系统中,默认情况下格式化 block 的数量会远大于 Inode 的数量),一旦 Inode 数量耗尽,就会导致系统无法写入文件而报出上述错误 "No space left on device"。

提示: 上述为 CentOS5 系统中的故障案例,同样适合于 CentOS6、 CentOS7,只是后两者小文件多的路径改为 postfix 的临时邮件队列目录了。

预防方法

尽量在 Cron 任务中的命令或脚本中的命令的结尾加上 ">/dev/null 2>&1",或者在写定时执行脚本时,将输出定向到指定文件中(适合于所有情况)。

当然也可以开启邮件服务,不过最好不做,因为邮件服务会带来额外的安全问题。

添加定时清理任务,比如,将 find /var/spool/postfix/maildrop/ type f -mtime +30|xargs rm -f 放入定时任务,每周处理一次(适合于 CentOS6 或 CentOS7)。

2、 Crond export 变量生产案例

编写一个重启 resin 的脚本,由于业务原因,需要在某一个时间定时重启一次 resin 服务器,于是就在 Cron 里面配置了如下内容:

复制代码
50 17 * * 1-5 root /usr/local/bin/resin_restart.sh

其中,resin_restart.sh 的内容具体如下:

复制代码
#!/bin/sh
/usr/local/bin/xxresin_stop.sh
/usr/local/bin/xxresin_start.sh

现在问题来了,服务器虽然定时重启了,但是系统却报出了如下错误:

复制代码
Resin can't load com.sun.tools.javac.Main.  
Usually this means that the JDK tools.jar is missing from the classpath,
possibly because of using a JRE instead of the JDK.
You can either add tools.jar to the classpath or change 
the compiler to an external one with <java compiler='javac
'/> or jikes.

为什么已经在 profile 里配置了环境变量,却还是找不到呢?

具体原因为 Crond 执行 Shell 时只能识别为数不多的系统环境变量, 普通环境变量一般是无法识别的,如果在编写的脚本中需要使用变量,那么最好是使用 export 重新声明下该变量,以确保脚本能够正确执行。以后要将这一点做为一个开发的基本规范。

然后再在 resin 重启脚本里重新定义了一下环境变量,脚本如下:

复制代码
#!/bin/sh
# 下面是环境变量的具体定义:
JAVA_HOME="/opt/jdk1.6.0_18"
CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:/opt/nginx
0.7.61/sbin:/opt/jdk1.6.0_18/bin:/opt/resin-3.0.25/bin:$PATH
export JAVA_HOME PATH USER LOGNAME MAIL HOSTNAME HISTSIZE 
INPUTRC CLASSPATH
/usr/local/bin/xxresin_stop.sh
/usr/local/bin/xxresin_start.sh

八、定时任务知识逻辑图(学习方法)

相关推荐
DogDaoDao14 小时前
【GitHub】RealtimeSTT 深度解析:打造低延迟、生产级语音识别应用的全栈利器
人工智能·语言模型·大模型·github·语音识别·stt·realtimestt
晚风予卿云月14 小时前
【Linux】初步构建框架—虚拟地址空间(三)—进程与内存管理的解耦优势、深入理解vm_area_struct
linux·运维·服务器·面试
2401_8685347814 小时前
华为系OSPF 配置命令全总结(2026 精简版
网络·数据结构
Oll Correct14 小时前
实验二十七:VLAN间单播通信实现方法——单臂路由
网络·笔记
摇滚侠14 小时前
阿里云镜像站 CentOS Tomcat Maven 等镜像资源
java·阿里云·centos
sbjdhjd14 小时前
从 0 到 1 构建高可用企业级 NoSql 数据库 Redis 集群
linux·运维·redis·云原生·kubernetes·开源·云计算
不知名的老吴14 小时前
WebSocket启用实时消息传递关键要点
网络·websocket·网络协议
梦奇不是胖猫14 小时前
[ 计算机网络 | 第三章 ] 数据链路层 06 无线局域网
网络·网络协议·计算机网络
zincsweet14 小时前
进程间通信入门:匿名管道的使用、阻塞场景与避坑指南
linux