【发布时间】:2018-09-23 00:45:31
【问题描述】:
我已经阅读了关于 SO 的其他类似标题的问题,但这不是这个问题的主题。我知道如何从另一个 PHP 脚本执行 PHP 脚本。问题是,当我这样做时,它使用了太多的 CPU。我想知道如何减少这种情况。
我有一个简单的类似前端控制器的脚本,名为 index.php。它处理来自客户端的 GET 请求,并根据传递的“action”参数,将请求发送到适当的文件以进行处理。例如,这是一个客户端请求:
xhttp.open("GET", serverURL + "?action=doSomething" + "&userID=" + user.ID + "&time=" + lastServerTime, true);
index.php 有一个将“action”参数映射到相应文件的数组:
exec('php ' . $url_map[$action] . ' "' . $parameter1 . '"' . ' "' . $parameter2 . '" 2>&1', $output, $return_value);
出于测试目的,我创建了一个 PHP 脚本,它除了测量 CPU 利用率并将其转储到日志文件之外什么都不做:
<?php
function varDumpToFile($parameter1) {
$file = 'log.txt';
$dump = $parameter1;
$output = print_r($dump, true);
file_put_contents($file, $output, FILE_APPEND | LOCK_EX);
}
varDumpToFile(`ps -eo pcpu,pid,user,args --no-headers| sort -t. -nk1,2 -k4,4 -r |head -n 5`);
?>
这会生成一个如下所示的日志文件:
9.0 3123052 user /opt/cpanel/ea-php56/root/usr/bin/php cputest.php 10 147424 1537625595
显然,PHP 脚本不应该占用 9% 的 CPU 来执行。为了比较,我运行了相同的脚本,通过 GET 请求直接访问它:
0.1 3186198 user lsphp:ic_html/dev/php/cputest.php
0.1% 更喜欢它。但是为什么从另一个 PHP 脚本调用这个 PHP 脚本会占用这么多 CPU 呢?是不是因为我在执行 PHP 时必须执行 PHP 的“新实例”,这会产生很多开销?如果是这样,有没有办法使用“已经运行”的 PHP 实例来执行 PHP 脚本?或者有其他方法吗?
【问题讨论】:
-
您是否有特定原因要使用 CLI 执行 PHP 文件?我以前从未见过有人这样做,这是一个严重的安全风险。除非您进行大量输入验证,否则有人会对您的网站做一些讨厌的事情。
-
通过 exec 调用它的原因是什么?为什么要考虑 CPU 使用率?您想更快地运行该过程吗?被调用的脚本做了哪些工作?如果您需要从 HTTP 请求周期中卸载在 exec() 方法中完成的工作,请查看消息队列系统,如 RabbitMq、ZeroMq
-
感谢大家的cmets。 Rob:我想这样做有一个非常具体的原因——被调用的文件必须在后台运行,而 index.php 必须立即响应 HTML 客户端。我从大量阅读 SO 中得到的理解是,调用“后台”PHP 文件是同时拥有这两者的唯一方法:在没有 index.php 脚本“等待”后台脚本在回复之前结束的情况下即时响应客户端客户端(可能需要几分钟),同时让后台脚本在后台愉快地运行而不会打扰任何人。
-
mblaettermann:我没有任何具体理由通过 exec 调用它,除非我认为这是正确的做法。我正在考虑 CPU 使用率,因为它限制了客户端可用的资源。每个客户端约 10%,即只有 10 个并发客户端。我不需要进程运行得更快(它在 1 毫秒内执行),但它确实需要使用更少的 CPU。感谢您的其他建议,但这是一个已经存在的具有大型代码库的应用程序,实际上运行得很好(除了这个问题)。我不会为了解决一个问题而改变整个架构。