与cron相比,如何更智能地调度服务器作业?


15

我每分钟都会工作以重新索引网站内容。

今天,搜索引擎死了,当我登录时,有数百个由cron启动的孤立进程。

是否有另一种方式使用某种现有软件,该软件可以让我每分钟执行一次作业,但是如果该作业没有返回(即由于搜索引擎进程失败),则不会启动另一个实例?


4
cron最有可能完全按照您的指示进行。我建议改为智能地重写作业。
gparent

Answers:


27

cron并不是问题所在,而是您的工作。

您将需要使您的工作与某些描述进行交互。最简单的方法是尝试创建目录,如果成功,则继续执行,否则退出。作业完成并退出后,应删除目录,以备下次运行。这是一个脚本来说明。

#!/bin/bash

function cleanup {
    echo "Cleanup"
    rmdir /tmp/myjob.lck
}

mkdir /tmp/myjob.lck ||  exit 1
trap cleanup EXIT
echo 'Job Running'
sleep  60
exit 0

在一个终端上运行它,然后在60秒钟启动之前,在另一个终端上运行它将以状态1退出。一旦第一个进程退出,您可以从第二个终端运行它...

编辑:

当我刚开始学习羊群时,我想我会更新这个答案。 flock(1)可能更易于使用。在这种情况下flock -n,似乎是适当的,例如

* * * * * /usr/bin/flock -n /tmp/myAppLock.lck /path/to/your/job   

会每分钟运行一次作业,但是如果flock无法获得文件锁,它将失败。


2
也许是愚蠢的问题,但是使用目录而不是常规文件有什么好处吗?
gparent

9
使用常规文件需要执行多项操作,请检查其是否存在,如果不存在则创建它。这为另一个创建文件的过程留下了机会。mkdir是一个原子操作,它可以工作并且您获得“锁”,或者由于另一个进程已经拥有它而没有。
user9517'4

说得通。在锁目录上也要考虑好。谢谢
John

2

一种方法是让您的重新索引脚本创建一个锁定文件,以便它可以检查是否已经在运行脚本实例。您还可以添加一些异常处理,以查看搜索引擎是否已启动并正在运行。

一个更复杂的选择是使用某种任务队列,例如Resque和Resque-scheduler:

https://github.com/blog/542-introducing-resque

https://github.com/bvandenbos/resque-scheduler#readme

还有Qu和Sidekiq:

https://github.com/bkeepers/qu

https://github.com/mperham/sidekiq

是的,这些都是面向Ruby的,但是您可以使用自己选择的语言查找“类似resque的东西”。


0

另一种快速设置方法是在计算机启动时启动shell脚本(cron可以使用' @reboot /path/to/my/script.sh',然后重新启动cron来启动它),其中包含类似这样的内容。

#!/bin/sh
/opt/bin/run-site-index
sleep 60
exec $0

该脚本一直在运行,您是否只启动了一个脚本-那就是一次可以运行的脚本数量-仅此而已。那里的一些聪明人还可以检查索引器是否正在运行,如果没有运行,请重新启动,否则尝试修复/通知某人该问题。


-3

除了使用cron之外,我还可以将您的工作更多地构建为循环运行的服务,并在最后一步睡眠60秒,或者在此过程中的各个时间点以较小的间隔更频繁地睡眠,以帮助分散负载更均匀。


1
这既不能解决问题,也不能改善cron。
gparent

它将解决此问题,因为那时只有一个进程在运行。它会完全回避cron。
Joel Coel 2012年

如果搜索引擎是否正在运行,则“服务”没有显示无法解决问题。他的剧本/工作的逻辑是问题。编辑:实际上,您是正确的,它将以丑陋的方式隐藏问题。
gparent
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.