如何比使用 cron 更智能地安排服务器作业?

如何比使用 cron 更智能地安排服务器作业?

我每分钟运行一次作业来重新索引我的网站内容。

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

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

答案1

问题实际上不是出在 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

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

一个更复杂的替代方法是使用某种任务排队器,如 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 的东西”。

答案3

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

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

脚本会持续运行,并且您只启动了一个脚本 - 即可以同时运行的脚本数量 - 不会超过这个数量。其中的一些智能功能还可以检查索引器是否正在运行,如果没有,则重新启动,或者尝试修复/通知某人该问题。

答案4

我不会使用 cron 来实现这个功能,而是将您的作业构建为一个服务,让它循环运行,并在最后一步休眠 60 秒,或者在整个过程中的各个点以较小的时间间隔更频繁地休眠,以帮助更均匀地分散负载。

相关内容