我在 Ubuntu 上运行了一堆 cron 作业(使用 设置sudo crontab -e
),最近(虽然我不知道什么时候可以确定)我突然发现相同的作业似乎在同一分钟内运行了多次。您无需查看完整的 crontab 即可相信我,它们绝对没有列出两次。但为了便于理解,这里有一个片段:
*/2 * * * * /usr/bin/wget --no-check-certificate 'https://myserver.net/someuri/pdm/33?embed_in_page=xyz'
* * * * * /usr/bin/wget --no-check-certificate 'https://myserver.net/someuri/pdm/77'
* * * * * /usr/bin/wget --no-check-certificate 'https://myserver.net/someuri/pdm/20?blah=blah'
* * * * * echo "`date` Running now" >> /home/somewhere/croncheck
我还在末尾添加了简单的回显,使其每分钟运行一次,并且它似乎从未运行过一次以上。
因此,对于 echo,我只看到它每分钟发生一次。但间歇性地,特别是在负载下,服务器似乎连续多次触发 wget URL 请求(通过查看网络服务器日志,我知道它们大致在同一时间来自同一位置)。
如果我跑ps -A |grep cron
我将看到十几个或更多如下所示的条目:
28055 ? 00:00:00 cron
它们似乎并没有消失。
如果我运行ps aux
,那么我只会看到我预期的一个条目。
因此,我猜测 wget 和 cron 之间存在令人讨厌的交互,并且可能某些东西以某种方式失败了(尽管服务器和通过 Web 浏览器对同一 Web 服务器的交互式调用似乎基本未受影响,只是因为不必要的工作而变慢了)。但事实是我不知道。我正在寻找您可能对原因以及问题的可能解决方案的任何想法。
答案1
虽然我不太清楚为什么会发生这种情况,但似乎是 cron 中长时间运行的作业导致了奇怪的行为。在原始帖子中,有一系列作业每五分钟触发一次,有些作业一分钟后触发一次。如果第一个作业花费的时间太长(例如 10 分钟),我猜第一个作业的分叉进程会停留十分钟并触发列表中的后续作业。但主 cron 进程也在正确触发这些作业,因此会出现重复,整个问题会层出不穷。
猜测得够多了。为了解决这个问题,下面是我的新 crontab 的一个片段,用于flock
阻止可能错误级联的后续作业。
# every 5 minutes
*/5 * * * * flock -w 2000 /tmp/cnsd.lockfile.pdm -c "/usr/bin/longrunningjob1"
# every 5 minutes
*/5 * * * * flock -w 2000 /tmp/cnsd.lockfile.pdm -c "/usr/bin/longrunningjob2"
# every 15 minutes past the hour
15 * * * * flock -w 2000 /tmp/cnsd.lockfile.pdm -c "/usr/bin/longrunningjob3"
这样至少当系统超载时,不会导致一系列本不应该被触发的作业,而是让所有作业都有机会恢复。我确实使用不同的 flock 锁文件尝试了不同类别的作业,但就我而言,我只有有限的资源,因此将一个作业排在另一个作业之后是保持系统运行的最佳方式。
答案2
验证网络日志是否多次显示完全相同的条目。如果是,请验证它们是否处于完全相同的时间。Cron 不是绝对的,正如所指出的,有时系统会负担过重。Cron 将“尝试”在规定的时间运行作业,但这不是绝对的,有时作业会比预期的晚运行,并且可能在同一作业的时间运行,然后您会看到两个条目。
另一个问题可能是某项工作耗时比预期的要长,而且在下一次迭代开始时仍在运行。我会从消除开始。注释掉除一项之外的所有项,让它运行并监控,然后添加下一项,再添加下一项,等等,看看会发生什么。