负载平衡Web服务器上的Cron任务

时间:2011-06-23 17:11:17

标签: php cron load-balancing

我正在寻找在负载平衡环境中处理我们的cron任务的更好解决方案。

目前有

  • 在负载均衡器后面的3个CentOS服务器上运行的PHP应用程序。
  • 需要定期运行但一次只能在一台计算机上运行的任务。
  • 好的旧cron设置为在第一台服务器上运行这些任务。
  • 如果第一台服务器由于某种原因而无法使用,则会出现问题。

寻找

  • 更强大,更集中的东西。
  • 对任务进行负载平衡,使多个任务只运行一次,但在随机/不同的服务器上运行以分散负载。
  • 防止第一台服务器出现故障时没有运行任务。
  • 能够管理任务并理想地使用网络界面查看汇总报告。
  • 通知如果出现任何问题。

解决方案不需要在PHP中实现,但它会很好,因为它可以让我们在需要时轻松调整它。

我发现了两个看起来很有希望的项目。 GNUBatchJob Scheduler。最有可能进一步测试两者,但我想知道是否有人有更好的解决方案。

感谢。

3 个答案:

答案 0 :(得分:5)

您可以使用这个使用redis创建临时定时锁的小型库:

https://github.com/AlexDisler/MutexLock

服务器应该相同并且具有相同的cron配置。首先创建锁的服务器也将执行该任务。其他服务器将看到锁定并退出而不执行任何操作。

例如,在执行计划任务的php文件中:

MutexLock\Lock::init([
  'host'   => $redisHost,
  'port'   => $redisPort
]);

// check if a lock was already created,
// if it was, it means that another server is already executing this task
if (!MutexLock\Lock::set($lockKeyName, $lockTimeInSeconds)) {
  return;
}

// if no lock was created, execute the scheduled task
scheduledTaskThatRunsOnlyOnce();

要以分散的方式运行任务并分散负载,请查看:https://github.com/chrisboulton/php-resque 它是resy版本的ruby版本的php端口,它以相同的格式存储数据,因此您可以使用https://github.com/resque/resque-webhttp://resqueboard.kamisama.me/来监控工作人员并查看报告

答案 1 :(得分:3)

假设您有一个未在这3台服务器之一上托管的数据库;

编写一个cron中的“wrapper”脚本,并将您正在运行的程序作为其参数。它首先做的是连接到远程数据库,并检查上次将条目插入表(为此包装器创建)的时间。如果上次插入时间大于应该运行的时间,则使用当前时间将新记录插入表中,然后执行包装器的参数(您的cron作业)。

每个服务器上的包装器,每个服务器设置在另一个服务器后面X分钟(服务器A在一小时内运行,服务器B在5分钟运行,C在10分钟运行等)。

第一台服务器将始终首先执行cron,因此其他两台服务器永远不会执行。如果第一台服务器出现故障,第二台服务器将看到它没有运行,并将运行它。

如果您还在表中记录了执行该作业的服务器,您将获得执行脚本的时间/位置的日志。

答案 2 :(得分:0)

这不是使用消息/任务队列的理想情况吗?