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



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

当前有

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

正在查找

  • 更稳健和去中心化的东西
  • 对任务进行负载平衡,使多个任务只运行一次,但在随机/不同的服务器上运行,以分散负载
  • 防止在第一台服务器关闭时不运行任务
  • 能够管理任务并查看聚合报告,最好使用web界面
  • 如果出现任何问题,请发出通知

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

我发现了两个看起来很有前景的项目。GNUBatch和Job Scheduler。很可能会进一步测试两者,但我想知道是否有人能更好地解决上述问题。

谢谢。

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

https://github.com/AlexDisler/MutexLock

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

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

MutexLockLock::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 (!MutexLockLock::set($lockKeyName, $lockTimeInSeconds)) {
  return;
}
// if no lock was created, execute the scheduled task
scheduledTaskThatRunsOnlyOnce();

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

假设您有一个可用的数据库,而不是托管在这3台服务器中的一台上;

编写一个cron中的"包装器"脚本,并将您正在运行的程序作为其参数。它所做的第一件事就是连接到远程数据库,并检查上次将条目插入表(为该包装器创建)的时间。如果最后一次插入时间大于它应该运行的时间,那么在表中插入一条具有当前时间的新记录,并执行包装器的参数(您的cron作业)。

在每台服务器上克隆包装器,每组比另一台晚X分钟(服务器A在一小时的顶部运行,服务器B在5分钟运行,C在10分钟运行,等等)。

第一个服务器总是先执行cron,所以其他两个服务器永远不会执行。如果第一台服务器出现故障,第二台服务器将看到它没有运行,并将运行它

如果您还在表中记录是哪个服务器执行了作业,那么您将有一个脚本执行时间/位置的日志。

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

我遇到了同样的问题,但得到了这个litte存储库:https://github.com/incapption/LoadBalancedCronTask

最新更新