执行长时间运行的PHP脚本的最佳实践

时间:2017-10-28 16:07:42

标签: php laravel symfony magento cron

我们需要分发应包含PHP脚本的软件,该脚本将运行几分钟。因此,我正在寻找2017年的最佳实践方法。

  • 必须由HTTP请求调用。应该没有HTTP请求等待几分钟,因此脚本必须在访问者获得HTTP响应后仍然运行。
  • 必须定期(每晚)。它也应该每晚默认运行(如cron作业)。注意:由于软件将分发给客户端,我们无法手动添加cronjob(我们无法访问客户端服务器)。一切都应该在PHP代码中完成。

(请注意我自己阅读了现有的博客文章和Stackoverflow问题,但我找不到令人满意的答案)

也许有人知道像Symfony和Laravel这样的框架或像Magento这样的网上商店如何完成这样的任务?我仍然想知道如何在不使用框架或库的情况下在普通PHP中自己完成。

3 个答案:

答案 0 :(得分:6)

存在许多解决方案:

  • 使用exec(相当不安全),触发后台作业(在评论中推荐,我可能更喜欢symfony进程,但不安全)。
  • 使用cron每隔一段时间触发一次symfony进程,而不是通过http进行更安全的触发。
  • 使用php-fpm,您可以使用fastcgi_finish_request
  • 发送响应,而无需停止该过程
  • 使用队列系统(SQS,RabbitMQ,Kafka等)。
  • 使用cron manager in PHP
  • 使用守护进程和supervisord之类的东西来确保它连续运行。

最好的解决方案绝对是队列和cron,然后是PHP-FPM,其余部分只是垃圾。

绝对没有办法在某人的服务器上运行而不做某些在某些时候无效的事情。

旁注:你说你不想要库来了解如何自己动手,我添加了库的链接,因为阅读它们可能会让你对这项技术有更深入的了解,这些库真的很高质量。

答案 1 :(得分:1)

Magento只运行cronjobs,如果你为Magento设置一个普通的cronjob。它有一个cron.sh,每分钟运行一次,在Magento的队列中执行作业。

通过http执行长时间运行任务的任何解决方案都涉及Web服务器配置。

答案 2 :(得分:0)

最后,我认为有两种方法可以通过HTTP请求在PHP中启动长时间运行的进程(不会让用户等待很长时间):

  • 使用FPM并使用fastcgi_finish_request()将响应发送给用户。发送响应后,您可以执行任何操作,例如长时间运行的任务。 (这里你不必开始一个新的过程,只需继续PHP)。

    fastcgi_finish_request();
    longrunningtask();
    
  • 使用以下某个功能创建新流程。将STDOUT和STDERR重定向为null并将其置于后台(您必须同时执行这两项操作)。为了仍然获得新进程的输出,新进程可以写入某个日志文件。

    exec('php longrunningtask.php >/dev/null 2>/dev/null &');
    shell_exec('php longrunningtask.php >/dev/null 2>/dev/null &');
    system('php longrunningtask.php >/dev/null 2>/dev/null &');
    passthru('php longrunningtask.php >/dev/null 2>/dev/null &');
    

    或者像proc_open()一样使用symfony/process

注意:

  • symfony/process:在您可以阅读的文档中,您可以使用FPM和fastcgi_finish_request()来执行长时间运行的任务。
  • 安全性:我看不到内置的安全风险,你只需要做正确的事情然后一切都很好(你可以使用密码保护,验证命令的可能输入等)。
  • 对于问题的cron-job部分,没有答案。我不认为这是可能的。