如何在不同的请求中运行PHP后台操作/处理方法?

时间:2018-08-16 11:10:49

标签: php symfony

我正在运行一个基于Symfony 2.8的Web应用程序。基本上,对服务器的每个请求都分三个步骤处理:

 1. User/Browser sends request to the server
 2. Server handles the request and performs any number of operations
 3. Server sends back the result as response to the user

在测试WebApp性能(=请求和响应之间的时间)时,我遇到了一个问题,我的代码运行了一堆代码,这些代码只是维护工作,并不是创建响应的真正必要:编写日志,添加响应的信息。请求统计信息等

 2. Server handles the request and performs any number of operations
     2a. Necessary work to answer the request
     2b. Maintenance work 

如果代码只需跳过所有这些步骤,而仅运行创建响应所必需的代码,则用户将获得完全相同的响应。

是否有可能将这项工作移至后台/另一个将维护工作与“实际”工作分开并更快地创建响应的请求?

在PHP中或者使用Symfony功能是否可能?

更准确地说:当然,“我的代码运行着一堆代码,只是为了维护……” 并不意味着每个请求都需要30秒才能完成删除维护代码会减少几毫秒的时间。

我很清楚,删除这些内容不会提高性能,并且将某些维护代码保留在“真实”代码中是比将所有内容“移至后台”更好的解决方案。

这是关于“如何将繁重的维护工作负载转移到后台处理不必要的工作”的一般问题。完全有可能在PHP中实现吗?

2 个答案:

答案 0 :(得分:1)

来自其他语言的这种说法很奇怪,但是对于PHP和Symfony来说都是很自然的。

PHP生命周期本身会初始化,并关闭每个请求的所有内容。这对安全性很有用(一个请求中的错误不会影响其他请求),但是对于速度而言却不是那么重要。

因此,同样适用于Symfony。一个请求进入,响应得到响应,一切都关闭(需要记录,刷新等)。 (旁注:SF能够处理多个请求-查看PHP-PM)

幸运的是,Symfony有一个kernel.terminate事件,该事件使您可以在发送响应后运行代码。 http://symfony.com/doc/current/components/http_kernel.html#the-kernel-terminate-event

这对于某些东西非常有用,但仅适用于php-fpm。 一个很好的例子是电子邮件的内存假脱机:https://symfony.com/doc/current/email/spool.html

Symfony在发送响应后延迟发送电子邮件。

您可以为用例做同样的事情,只需要一个kernel.terminate侦听器。您提到了某种请求状态...这将是创建和保存请求的好地方。

您还提到了日志记录:我不会对此太担心。在生产模式下,多亏了手指交叉的处理程序,因此只会记录错误。 https://symfony.com/doc/2.0/cookbook/logging/monolog.html#handlers-and-channels-writing-logs-to-different-locations

  

Monolog还带有一个用于在产品环境中进行记录的功能强大的内置处理程序:FingersCrossedHandler。它允许您将消息存储在缓冲区中,并仅在消息达到操作级别(标准版本提供的配置中为ERROR)时才将消息转发到另一个处理程序,以记录消息。

如果您认为登录文件太慢,也可以更改日志存储。我使用API​​(滚动条)记录错误,并且它根本不会影响性能-除非出现错误,否则我担心的最少是30毫秒左右的响应时间。

答案 1 :(得分:0)

让我们说您想在index.php上运行2a。您的要求是您不想等待index.php完成后再发送响应。

您可以按照以下步骤进行操作:

$cmd="php index.php";
if (substr(php_uname(), 0, 7) == "Windows"){
    pclose(popen("start /B ". $cmd, "r"));
} else {
    exec($cmd . " > /dev/null &");
}