gpt4 book ai didi

php - 加速 PHP 应用程序

转载 作者:行者123 更新时间:2023-11-29 01:08:21 26 4
gpt4 key购买 nike

我有一个需要处理的数据列表。它现在的工作方式是这样的:

  • 用户点击流程按钮。
  • PHP 代码获取需要处理的第一个项目,需要 15-25 秒来处理它,然后继续处理下一个项目,依此类推。

这花费的时间太长了。我想要的是:

  • 用户点击处理按钮。
  • PHP 脚本获取第一项并开始处理它。
  • 同时,脚本的另一个实例获取下一个项目并对其进行处理。
  • 依此类推,大约有 5-6 个项目同时被处理,我们在 15-25 秒内处理了 6 个项目,而不是一个。

这样的事情可能吗?

我在想我使用 CRON 每秒启动一个脚本实例。所有需要处理的项目都将在 MySQL 数据库中标记为此类,因此无论何时通过 CRON 启动实例,它都会简单地获取下一个标记为要处理的项目并删除该标志。

想法?

编辑:为了澄清一些事情,每个“项目”都作为单独的行存储在 mysql 数据库表中。每当对一个项目开始处理时,它都会在数据库中被标记为正在处理,因此每个新实例将简单地获取未被处理的下一行并处理它。因此,我不必将这些项目作为命令行参数提供。

最佳答案

这是一个解决方案,不是最好的,但可以在 Linux 上正常工作:

将处理 PHP 拆分为单独的 CLI 脚本,其中:

  • 命令行输入包括 `$id` 和 `$item`
  • 脚本将其 PID 写入 `/tmp/$id.$item.pid` 中的文件
  • 该脚本将结果作为 XML 或可以读入 PHP 的内容回显到标准输出
  • 脚本完成后删除 `/tmp/$id.$item.pid` 文件

你的主脚本(大概在你的网络服务器上)会做:

  • `exec("nohup php myprocessing.php $id $item >/tmp/$id.$item.xml");` 为每个项目
  • 轮询 `/tmp/$id.$item.pid` 文件,直到所有文件都被删除( sleep /检查轮询就足够了)
  • 如果它们从未被删除,则终止所有处理脚本并报告失败
  • 如果成功,从 `/tmp/$id.$item.xml` 读取格式/输出给用户
  • 如果您不想缓存供以后使用,请删除 XML 文件

后台 nohup 启动的应用程序将独立于启动它的脚本运行。

这让我很感兴趣,因此我决定编写一个 POC。

测试.php

<?php
$dir = realpath(dirname(__FILE__));
$start = time();

// Time in seconds after which we give up and kill everything
$timeout = 25;

// The unique identifier for the request
$id = uniqid();

// Our "items" which would be supplied by the user
$items = array("foo", "bar", "0xdeadbeef");

// We exec a nohup command that is backgrounded which returns immediately
foreach ($items as $item) {
exec("nohup php proc.php $id $item > $dir/proc.$id.$item.out &");
}

echo "<pre>";
// Run until timeout or all processing has finished
while(time() - $start < $timeout)
{
echo (time() - $start), " seconds\n";
clearstatcache(); // Required since PHP will cache for file_exists
$running = array();
foreach($items as $item)
{
// If the pid file still exists the process is still running
if (file_exists("$dir/proc.$id.$item.pid")) {
$running[] = $item;
}
}
if (empty($running)) break;
echo implode($running, ','), " running\n";
flush();
sleep(1);
}

// Clean up if we timeout out
if (!empty($running)) {
clearstatcache();
foreach ($items as $item) {
// Kill process of anything still running (i.e. that has a pid file)
if(file_exists("$dir/proc.$id.$item.pid")
&& $pid = file_get_contents("$dir/proc.$id.$item.pid")) {
posix_kill($pid, 9);
unlink("$dir/proc.$id.$item.pid");
// Would want to log this in the real world
echo "Failed to process: ", $item, " pid ", $pid, "\n";
}
// delete the useless data
unlink("$dir/proc.$id.$item.out");
}
} else {
echo "Successfully processed all items in ", time() - $start, " seconds.\n";
foreach ($items as $item) {
// Grab the processed data and delete the file
echo(file_get_contents("$dir/proc.$id.$item.out"));
unlink("$dir/proc.$id.$item.out");
}
}
echo "</pre>";
?>

proc.php

<?php
$dir = realpath(dirname(__FILE__));
$id = $argv[1];
$item = $argv[2];

// Write out our pid file
file_put_contents("$dir/proc.$id.$item.pid", posix_getpid());

for($i=0;$i<80;++$i)
{
echo $item,':', $i, "\n";
usleep(250000);
}

// Remove our pid file to say we're done processing
unlink("proc.$id.$item.pid");

?>

将 test.php 和 proc.php 放在服务器的同一个文件夹中,加载 test.php 并享受。

你当然需要 nohup (unix) 和 PHP cli 来让它工作。

很有趣,以后我可能会发现它的用处。

关于php - 加速 PHP 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2106247/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com