【问题标题】:How can I do background parsing of data with Symfony2?如何使用 Symfony2 对数据进行后台解析?
【发布时间】:2012-06-03 08:21:45
【问题描述】:

我用 Symfony2 用 PHP 编写了一个 Web 应用程序。用户可以上传包含保存到数据库中的数据的 CSV 文件。 CSV 文件每一行的解析持续大约 0.2 秒,因为我向 Google Maps API 发出了一些请求。

因此,当您上传包含 5000 行的 CSV 文件时(在我的应用中这是一个实际情况),解析整个文件可能需要 16 分钟。

我不希望用户必须等待 16 分钟才能继续使用我的应用。所以我的问题是:如何在后台解析CSV文件,让用户继续上网?

【问题讨论】:

  • Symfony2 没有开箱即用的后台进程/worker 功能,所以你必须自己动手。
  • 我会选择 Gearman - 易于设置并且确实可以很好地与 PHP 配合使用。

标签: php parsing symfony background


【解决方案1】:

您可以创建一个kernel.terminate 事件侦听器并在那里进行解析。此事件在响应发送到浏览器后触发。示例实现是,

服务声明,

//services.yml
csv_parse_listener:
    class: FQCN\Of\CsvParseListener
    tags:
        - { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate }

监听类,

namespace Your\namespace;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;

class CsvParseListener
{
    public function onKernelTerminate(PostResponseEvent $event)
    {
        $request = $event->getRequest();
        if($request->get('_route') !== "Your_route"){
            return;
        }

        $csvFile = $request->files->get('file_field_name');

        //move file using $csvFile->move()
        //read and parse
    }
}

【讨论】:

  • 事件“kernel.terminate”是否可以在 Symfony2 中调用?当我想使用我的 Web 应用程序时,它会引发错误。
  • 为什么要直接调用呢?如果已注册,则将自动调用 onKernelTerminate 方法。错误信息是什么?
  • 错误是我犯的 ;) 但是现在 onKernelTerminate 方法没有被调用,我的应用程序没有运行这个方法中的代码。我查看了文件vendor\symfony\src\Symfony\Component\HttpKernel\KernelEvent,但没有“终止”事件。
  • 奇怪,应该在课程的最后,const TERMINATE = 'kernel.terminate';。你的 Symfony 版本是多少?
  • 我的 Symfony 版本是 2.0.15,是最新的。
【解决方案2】:

让上传将作业插入作业队列表,并让cron 定期运行Command 来处理作业队列表中的任何工作。

随着作业处理的进行,您可以更新作业表,以便用户可以检查并查看正在发生的进度(例如,您可以有一个 ajax 进度条)并知道作业何时完成。

通过这种方式,您还可以将上传与处理分离,并且您可以控制一次处理多少个作业。在没有限制/排队系统的情况下直接从用户输入启动长时间运行的作业是让自己面临拒绝服务攻击的好方法......

【讨论】:

  • 这听起来是个好主意。我会这样尝试。谢谢:)
【解决方案3】:

您可以编写一个仅用于处理 CSV 文件的脚本,然后从管理上传的脚本中执行该脚本。在 *IX 系统上,您可以通过附加 & 字符使由 exec() 启动的命令在后台运行。

您可能还需要包含一个脚本,让用户检查处理进度。

【讨论】:

  • 从 Web 请求中执行长时间运行的作业对我来说听起来很冒险。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 2018-03-29
  • 2011-06-30
相关资源
最近更新 更多