在我的应用程序服务上处理文件的替代方案

Alternative to processing files on my app service

我目前正在使用我的应用程序服务来处理文件。我正在上传 Excel 个文件并使用 PhpSpreadsheet 处理它们。

在本地,他们将在不到 90 秒的时间内完成(笔记本电脑、SSD、i7、16GB RAM)。在我的应用程序服务(小型 Linux 计划)中,相同的文件和脚本可能需要 10 分钟以上的时间。这会导致 504 网关超时错误。然后我在数据库中手动确认数据上传。

有什么方法可以替代这种处理文件的方式?

编辑#1

通过处理,我的意思是上传一个 Excel 文件,遍历行,提取数据并使用 PhpSpreadsheet 更新数据库。我当前的文件是 102KB,有 4300 行,23 列,大约需要 6 分钟。在本地,只有几秒钟。

示例:

if ($this->request->is('post')) 
{
    $file = $this->request->getData()['my_file'];
    $path = TMP.time()."_".$file->getClientFileName();
    $file->moveTo($path);

    $spreadsheet = IOFactory::load($path);
    $sheetData = $spreadsheet->getActiveSheet()->toArray(null, false, true, true);

    foreach($sheetData as $sheet_row)
    { ... }
}

评论提供了一些关于基本选项的好想法,简要总结:

  1. 使用更快的服务器
  2. 使您的算法更快地解析您的文件(无论它是什么)。

两者都可能在短期内缓解您的问题。但是,假设您的算法是 well-optimized 并且您的服务器的速度与您愿意支付的速度一样快,这两者对您来说可能都是正确的,并且在 real-world 情况下通常也是如此。我们还假设您的文件大小有些不可预测,因此即使 well-optimized 并且速度很快,您也可能需要支持处理速度较慢的较大文件的异常情况。

听起来您的工作流程是(同步):

  1. 客户端使用 Excel 文件向服务器发送 HTTP 请求
  2. PHP 服务器运行文件解析
  3. 服务器 returns 一个 HTTP 200(正常)和解析完成后的文件。如果请求花费 > 600 秒(或任何超时时间),它将超时并且 returns 504.

我同意建议删除第 2 步并将其放入 background-job processing 的评论。这将使您的工作流程看起来像:

  1. 客户端使用 Excel 文件向服务器发送 HTTP 请求
  2. 服务器将 Excel 文件异步发送到后台作业处理器,开始处理但不等待它完成。
  3. 服务器 returns HTTP“201 已创建”表示服务器已开始处理文件。
  4. 客户端每 n 秒轮询一次服务器上的作业状态端点以检查作业是否完成

有很多不同的方法可以做到这一点(上面的后台处理 link 详细介绍了一些 Azure-esque 方法)。

我能想到的一个 Azure-centric 方法是使用 function app triggered by a queue。在这种情况下,您的服务器可以接受一个 Excel 文件,将其保存在某处(或者您的客户端可以将其直接上传到 Azure Blob 存储),然后向您的队列添加一个条目,说明要处理的文件在哪里.使用队列触发器,这可以自动触发您的功能应用程序代码,它可以从您的队列中提取最旧的消息,找到要处理的文件,在尽可能多的时间内处理它,然后上传“处理过的” " 文件返回到 blob 存储以供客户端使用。

我对 PHP 后台作业工具知之甚少,因此 Azure-ness 以上建议,但肯定有许多其他方法可以完成上面提出的相同基本工作流,并且好处以上是你可以使用基本上任何你想要的语言来实现它,核心架构保持不变。