nginx:触发慢速php-fpm进程,但快速返回状态200

时间:2016-08-02 14:50:54

标签: php nginx

nginx是否可以触发php-fpm进程,但是然后关闭nginx worker并快速返回状态为200的空白页?

我有一些缓慢的PHP进程,需要每周开几次。它们每个可能需要3到4分钟。我用cron manager site触发它们。 php进程在开始时写入一个锁定文件,当进程完成时,会发送一封电子邮件,最后删除锁定文件。

关注this guide,在我的php-fpm工作池中,我有:request_terminate_timeout = 300并且在我的nginx网站配置中我有fastcgi_read_timeout 300;

它有效,但我不关心屏幕上的结果。我使用的cron服务的时间限制为5秒,并且在重复超时后,它会禁用该作业。

是的,我知道我可以在php中分叉一个进程,让它在后台运行,并返回200到nginx。是的,我可以支付并升级我的cron服务。尽管如此,无论如何,要知道这将是一件有趣且有用的事情。

那么,这是可能的,还是php-fpm需要一个开放的“直播”套接字?我问,因为在上面提到的“增加你的超时”页面上,有一个答案说

  

“最低的三个。它是直线链.Nginx-> PHP-FPM-> PHP。谁死了   首先会打破链条“。

换句话说,这是否意味着我永远不会“触发”一个过程,但是然后关闭触发器的nginx部分?

2 个答案:

答案 0 :(得分:2)

你可以。

  1. 通过添加尾随&来执行php cli脚本,将输出重定向到日志文件或/dev/null,将任何参数传递为json或序列化(使用escapeshellarg()),exec将立即返回0(无错误);或
  2. 使用php' ignore_user_abort(),发送Connection: close标头,刷新任何输出缓冲区以及普通flush()。之后放任何慢代码。您需要在Nginx下进行测试。
  3. 无论哪种方式,都返回1xx代码以表示接受但没有回复。并且你要确保你的脚本不会永远运行;给它一个心跳,所以touch()经常出现一个文件。如果文件已经过时且仍在运行,请将其删除。

答案 1 :(得分:0)

感谢@Walf's answer结合this example from the php sitethis SO answer以及一点点摆弄,这似乎是nginx的解决方案,不需要搞乱任何php或nginx ini或conf文件。

$start = microtime(true);
ob_end_clean();
header("Connection: close\r\n");
header('X-Accel-Buffering: no');
header("Content-Encoding: none\r\n");
ignore_user_abort(true); // optional
ob_start();
echo ('Text user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();     // Strange behaviour, will not work
flush();            // Unless both are called !
ob_end_clean();
sleep(35); // simulate something longer than default 30s timeout
$time_elapsed_secs = microtime(true) - $start;
echo $time_elapsed_secs; // you will never see this!

或者,至少,它完全符合我的要求。谢谢你的回答。