我有一个 cron 任务:
1 0 * * * /usr/bin/wget -q -O /dev/null 'http://123.456.78.90/index/parsedata?&today=1'
它应该每天凌晨 12:01 从数据库收集大量数据,将其组织起来以供我们的应用程序在图表和显示中使用,然后完成。
有时,某些图表似乎没有被处理,因为它们在一段时间内没有显示结果。手动运行命令将使它们具有正确的数据。
因此,cron 似乎是问题的一部分。要么是 cron 没有触发这个,事实并非如此,因为我看到大多数条目都显示预期的图形数据,要么是 cron 没有完成?我不知道该去哪里找,因为我觉得既然手动触发上述脚本行有效,那么当我设置 cron 来执行它时,为什么它不能以相同的方式工作?有什么想法吗?
在同一台服务器上还有另外一项 cron 作业,每 5 分钟运行一次,使用相同的代码:
*/5 * * * * /usr/bin/wget -q -O /dev/null http://123.456.78.90/index/parsedata
第一次运行是否可能耗时太长,并且当这个每 5 分钟运行一次的脚本启动时仍在处理,这会把事情搞乱吗?第一个脚本可能需要超过 5 分钟才能运行,因此第二个实例可以在第一个脚本仍在运行的同时运行。它们都在我们的框架中使用相同的操作 parsedata(),并写入相同的数据库。可能吗?任何想法都值得赞赏。
答案1
作业在 cron 中失败但在终端上运行通常表明该作业正在尝试产生输出或stdout
但stderr
因为无法产生输出而失败。
听起来你需要一些日志记录。尝试重定向stdout
到stderr
文件以更好地了解正在发生的事情:
/usr/bin/wget -q -O /dev/null http://123.456.78.90/index/parsedata >> /tmp/somelogfile.txt 2>&1
如果生成了一些输出,那么也许它会让您了解问题的根本原因。如果作业失败后日志文件仍然是空的,那么至少您知道要去别处查找。
答案2
如果您的两个进程在数据库中陷入死锁情况,那么这可能是较长作业失败的原因(它被选为被终止以解决死锁的任务)。如果是这种情况,或者如果其他错误导致进程失败,您可能会发现您的parsedata
脚本正在返回有用的错误消息(或其他线索),但您永远不会看到它,因为您正在用 丢弃其输出-O /dev/null
。我建议您记录输出而不是将其发送到/dev/null
,例如:
-O /var/log/dailyparsedata/`date +%Y%m%d_%H%M`
(注意:这些是反引号,而不是单引号)将每天在 中创建一个新文件/var/log/dailyparsedata/
。您可以设置另一个 cron 作业(或配置 logwatch)来删除超过给定年龄的文件,这样您就不会随着时间的推移用这些文件填满分区。
此外,可能存在错误情况,wget
甚至无法看到脚本的输出(可能由于某种原因,它有时甚至无法看到 Web 服务器:如果它调用的服务器是远程的,则很有可能),在这种情况下,它将没有任何内容输出到指定的文件-O
,因此除了记录脚本输出外,还要记录 wget 的 stdout 和 stderr,如 Stephen 的回答所建议的那样。由于您的 cron 行目前处于大多数 cron 实现的状态,因此大多数 cron 实现都会将部分输出作为电子邮件发送给某人,而添加>> /var/log/dailyparsedata/wget.output 2>&1
会将该信息保存在文件中。我会避免发送这种输出,/tmp
因为那里有两个风险:用日志填充 /tmp,因此它的主要用途会中断,并且服务器重启时默认会清除它,这意味着您会丢失以后可能想要检查的日志。