Linux 系统定时任务Cron(d)服务应用实践(三:定时任务调试技巧及故障分析解决)
Linux 系统定时任务 Crond服务应用实践六、调试 Cron 定时任务的技巧总结1、增加执行任务的频率以调试任务在调试时将任务执行频率调快一点例如每天执行的任务可以改为每分钟、每 5 分钟执行一次或者以当前时间为准推迟 5 分钟以后看能否执行而且是不是按照你想要的去执行。如果正常没问题了那么再改成需要的任务的执行时间。需要强调一点的是有些计划任务是不允许频繁执行的。例如定时向数据库里插入数据这样的任务就要在测试机上先测试好然后再部署到正式线上这样正式工作时出问题的机率就少了。专业、规范的公司开发和运维人员配置服务器的操作流程至少是 办公室测试环境→ IDC 机房测试环境→ IDC 机房正式环境在不同的环境上测试成功再到更高级的环境是保障操作人员在正式环境下不出错的关键。2、调整系统时间调试任务不能用于生产环境用正确的执行任务的时间测试完成以后即可修改系统的当前时间改成任务执行时间的前几分钟来进行测试或者重启定时任务服务。例如定时任务于 900 执行那么我们可以将系统时间改成 855 分然后观察是不是正确执行了当前时间比任务时间建议提前 3 分钟以上否则可能就不会执行如果是生产环境服务器则尽量不要修改时间测试在测试环境下才可以使用这个手段。例如若是要在周三的 200 执行则可以将系统时间调整为周三凌晨 155 分查看执行结果。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 21提示 对于不好查看执行结果的定时任务计划可以这样调试在脚本命令中通过参数打印信息输出然后将输出重定向到指定的文件示例代码如下[rootshy scripts]# cat tar.sh cd / tar zcvf /tmp/etc_$(date %F).tar.gz ./etc /tmp/tmp.log 21 # 加 v 参数结尾重定向到文件。4、通过 Crond 定时任务服务日志调试定时任务查看定时任务服务的日志可以发现执行的以及不能执行的任务问题所在示例日志信息如下[rootshy scripts]# tail -f /var/log/cron May 27 21:07:01 shy CROND[4139]: (root) CMD (echo oldboyserver/log/oldboy.log) May 27 21:08:01 shy CROND[4142]: (root) CMD (echo oldboyserver/log/oldboy.log) May 27 21:09:01 shy CROND[4146]: (root) CMD (echo oldboyserver/log/oldboy.log) May 27 21:10:01 shy CROND[4149]: (root) CMD (echo oldboyserver/log/oldboy.log) May 27 21:11:01 shy CROND[4154]: (root) CMD (echo oldboyserver/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-queuerm -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 21”或者在写定时执行脚本时将输出定向到指定文件中适合于所有情况。当然也可以开启邮件服务不过最好不做因为邮件服务会带来额外的安全问题。添加定时清理任务比如将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 cant 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 compilerjavac / 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八、定时任务知识逻辑图学习方法