每 5 分钟运行一次 PHP 脚本并避免竞争条件

2022-01-04 00:00:00 cron php

我有一个需要每 5 分钟运行一次的 php 脚本.目前我正在使用 cron 作业来运行它(并且效果很好),但我的主机只允许至少 15 分钟的时间.

I have a php script that needs to run once every 5 minutes. Currently I'm using a cron job to run it (and it works great) but my host only allows a minimum time of 15 minutes.

所以我的问题是,我可以使用访问者每 5 分钟触发一次 php 脚本的运行吗?我可以轻松地记录上次运行的时间,然后根据经过的时间重新运行.

So my question is, can I use visitors to trigger the running of a php script every 5 minutes. I can easily just record the last time it ran, and re-run it based on elapsed time.

但是,我担心竞争条件.重要的是脚本每 5 分钟只运行一次.

However, I'm worried about race conditions. It is important that the script only gets run once every 5 minutes.

我的脚本需要大约 60 秒才能运行.在此期间它会写入几个文件.如果脚本运行不止一次,它会损坏文件.另外,如果我在 10 分钟内没有访问者,那么在下一个访问者到达时运行一次就可以了.

My script takes about 60 seconds to run. It writes to a couple files during this time. If the script ran more than once it would corrupt files. Also, if I get no vistors for 10 minutes, then running once when the next vistor arrives is fine.

是否有一些标准方法可以完成此任务?

Is there some standard way to accomplish this task?

谢谢!

推荐答案

您是否考虑过让您的脚本运行无限循环并带有 sleep 以在迭代之间等待 5 分钟?

Have you considered just having your script run an infinite loop with a sleep to wait 5 minutes between iterations?

for (;;)
{
  perform_actions();
  sleep(300);
}

或者,您可以拥有一个文件(例如,is_running),并获得一个独占的 在脚本开始时锁定,并在最后释放.至少这样你就不会做任何破坏性的事情.

Alternatively, you could have a file (for example, is_running), and get an exclusive lock on it at the start of your script which is released at the end. At least this way you will not do anything destructive.

您也可以将这两种解决方案结合起来.

You could also combine these two solutions.

$fp = fopen("is_running", "r+");

/* is it already running? */
if (! flock($fp, LOCK_EX | LOCK_NB)) return;

for (;;)
{
  perform_actions();
  sleep(300);
}

然后让 cron 作业每 15 分钟运行一次.如果进程仍在运行,它就会退出,否则它会重新启动并每 5 分钟恢复更新一次.

And then have the cron job still run every 15 minutes. If the process is still running, it will just bail out, otherwise it will relaunch and resume updating every 5 minutes.

相关文章