我有一个位于/var/www/site/update.php full
的PHP脚本。该脚本从cron自动启动:
/usr/bin/php /var/www/site/update.php full
但是当我从我的网站启动相同的脚本时:
<?php exec("/usr/bin/php /var/www/site/update.php full") ?>
它运行大约20分钟,然后开始显示很多错误消息。同时,页面停止加载并将error 504 Gateway Time-out
写入屏幕。
我想卷曲也无济于事。还有其他选择吗? 问题是如何运行,使其可以独立于浏览器运行。该代码已经存在并且已经解决。现在,它每小时都要经过cron。但是需要通过按网站上的按钮或链接来按计划运行它。
答案 0 :(得分:0)
您可以在PHP脚本中修改set_time_limit(-1);
以防止PHP死亡,但是504声音听起来好像您正在运行nginx,因此您还必须使用location
配置修改该特定资源的时间限制节点(或主要ngix配置)以设置* _timeout设置
如果您不需要每秒刷新一次输出,我会这样做:
按下按钮时,将“已按下”标志存储在某些文件中
if($ _ POST ['schedule_script_button']){ 触摸( DIR 。” / script_is_scheduled.flag“); }
使用cron每分钟运行一次脚本
* * * * * php /var/www/example.com/my-long-script.php
脚本必须检查该标志是否已设置,否则终止
if(!file_exists( DIR 。“ / script_is_scheduled.flag”)){ 出口; } //此处执行完整的脚本逻辑
如果设置了标志,请运行脚本并将输出保存到文件中。如果要使用crontab,则可以在脚本中使用echo,并且crontab应该进行如下修改:
* * * * * php /var/www/example.com/my-long-script.php > /var/www/example.com/my-script-output.txt
my-script-output.txt
PHP函数来读取file_get_contents
,并简单地回显其内容。我反对将Web URL的执行限制设置为较高的值,攻击者可以利用此限制通过长时间执行脚本来占用其网站资源
答案 1 :(得分:0)
您要实现的目标无法在PHP Web范例中完成:您的脚本在HTTP请求的上下文中运行;一旦访问者中断请求(关闭选项卡或浏览器,关闭WiFi等),其执行就会被终止。
为了从HTTP请求(单击按钮或以编程方式的curl调用)触发执行长时间的后台任务,您的服务器必须由更多成分组成:通常是消息队列(例如{ {3}}。
单击按钮只会触发一个Job消息:将(字符串)消息放入Message Queue中,该消息描述要运行的执行类型以及参数(例如,以PHP序列化的方式或JSON)–和然后立即返回。您的访客会收到快速的HTTP响应,上面写着“您的作业已成功排队”。
然后,除了Message Queue成分外,您还必须运行一个连续运行的进程(在PHP CLI中具有无限的时间限制,或者是您选择的任何一种语言的守护程序)。这个无限循环的脚本使自己处于针对Message Queue服务的侦听模式(订户),并且每次收到消息时,它都会执行您需要的任何长时间处理。
您的访客可以在其正在运行的工作的专用页面上查询长期工作的状态,他们还可以在其中获得下载或查看结果的结果。(例如:各种“将YouTube转换为Mp3”服务网络)
这是处理在线触发的长时间后台任务的唯一可靠方法。
您可以使用多种中间件来实现此目的:RabbitMQ,RabbitMQ,Redis是一些示例,具体取决于您的具体情况(根据注意事项,例如守护程序实例的数量,对队列中待处理消息的优先级管理的需要,或在发生故障时保持队列的持久性等)
您可以在RabbitMQ Kafka中找到方法。
答案 2 :(得分:0)
我按照本讨论php execute a background process中的建议进行了操作。页面仍未加载,但结果是。它可能不是最好的解决方案,但它可以工作。我希望有更好的解决方案。