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

发布于 2024-11-17 00:40:13 字数 795 浏览 2 评论 0原文

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

当前

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

寻找

  • 更强大、更去中心化的东西。
  • 对任务进行负载平衡,以便多个任务仅运行一次,但在随机/不同的服务器上运行以分散负载。
  • 防止当第一台服务器出现故障时任务无法运行。
  • 能够使用 Web 界面管理任务并查看汇总报告。
  • 如果出现任何问题,会发出通知。

该解决方案不需要用 PHP 实现,但它会很好,因为它允许我们在需要时轻松调整它。

我发现了两个看起来很有前途的项目。 GNUBatch作业调度程序。很可能会进一步测试两者,但我想知道是否有人对上述问题有更好的解决方案。

谢谢。

I'm looking for better solution to handling our cron tasks in a load balanced environment.

Currently have:

  • PHP application running on 3 CentOS servers behind a load balancer.
  • Tasks that need to be run periodically but only on a single machine at a time.
  • Good old cron set up to run those tasks on the first server.
  • Problems if the first server is out of play for whatever reason.

Looking for:

  • Something more robust and de-centralized.
  • Load balancing the tasks so multiple tasks would run only once but on random/different servers to spread the load.
  • Preventing not having the tasks run when the first server goes down.
  • Being able to manage tasks and see aggregate reports ideally using a web interface.
  • Notifications if anything goes wrong.

The solution doesn't need to be implemented in PHP but it would be nice as it would allow us to easily tweak it if needed.

I have found two projects that look promissing. GNUBatch and Job Scheduler. Will most likely further test both but I wonder if someone has better solution for the above.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花之痕靓丽 2024-11-24 00:40:13

您可以使用这个使用 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
它是 resque 的 ruby​​ 版本的 php 端口,它以完全相同的格式存储数据,因此您可以使用 https ://github.com/resque/resque-webhttp://resqueboard.kamisama.me/< /a> 监视工人并查看报告

You can use this small library that uses redis to create a temporary timed lock:

https://github.com/AlexDisler/MutexLock

The servers should be identical and have the same cron configuration. The server that will be first to create the lock will also execute the task. The other servers will see the lock and exit without executing anything.

For example, in the php file that executes the scheduled task:

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();

To run the tasks in a de-centralized way and spread the load, take a look at: https://github.com/chrisboulton/php-resque
It's a php port of the ruby version of resque and it stores the data in the same exact format so you can use https://github.com/resque/resque-web or http://resqueboard.kamisama.me/ to monitor the workers and see reports

黯然 2024-11-24 00:40:13

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

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

在每台服务器上运行包装器,每台服务器落后 X 分钟(服务器 A 在整点运行,服务器 B 在 5 分钟运行,服务器 C 在 10 分钟运行,等等)。

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

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

Assuming you have a database available not hosted on one of those 3 servers;

Write a "wrapper" script that goes in cron, and takes the program you're running as its argument. The very first thing it does is connect to the remote database, and check when the last time an entry was inserted into a table (created for this wrapper). If the last insertion time is greater than when it was supposed to run, then insert a new record into the table with the current time, and execute the wrapper's argument (your cron job).

Cron up the wrapper on each server, each set X minutes behind the other (server A runs at the top of the hour, server B runs at 5 minutes, C at 10 minutes, etc).

The first server will always execute the cron first, so the other two servers never will. If the first server goes down, the second server will see it hasn't ran, and will run it.

If you also record in the table which server it was that executed the job, you'll have a log of when/where the script was executed.

扬花落满肩 2024-11-24 00:40:13

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

Wouldn't this be an ideal situation for using a message / task queue?

王权女流氓 2024-11-24 00:40:13

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

I ran into the same problem but came up with this litte repository:
https://github.com/incapption/LoadBalancedCronTask

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文