将脚本功能卸载到后响应:方法和最佳实践?

时间:2009-10-11 00:17:44

标签: php optimization web-applications offloading

首先,

设置:

我有一个脚本,在用户点击“上传”按钮后执行多个任务,该按钮向脚本发送所需的数据。现在,这个部分目前是强制性的,我们目前没有选择删除上传和从实时来源中提取。

本节故意啰嗦一提。如果你讨厌

,请跳过去

现在,使用正则表达式从一个非常时髦的源解析数据,然后分解为数组。然后,它会检查数据库中是否有已上载数据日期范围内的任何数据。如果数据库中尚不存在数据日期范围,它会插入数据并将成功输出给用户(还有一些安全检查,数据源验证和基本上载验证)...如果数据确实存在,然后,脚本获取数据库中已存在的数据,查找两组之间的差异,删除不匹配的旧数据,添加新数据,然后向受这些更改影响的每个人发送电子邮件(每封一封电子邮件)所述电子邮件中所有相关更改的人,这是另一个步骤)。电子邮件地址是通过LDAP搜索提取的,因为我们的数据库有他们的工作电子邮件,但LDAP有他们的个人电子邮件,确保他们在第二天进入之前收到电子邮件并且不知不觉被抓住。最后,数据上传者被告知“已经进行了更改,已发送电子邮件”。他们真的非常关心。

现在,我可能会添加一个Google Calendar API,用于将数据(在调度数据时)发布到用户的Google日历。我会通过他们的工作日历来做到这一点,但我认为在处理为Exchange设置WebDav系统之前,我会先使用谷歌的API。

</backstory>

现在!

实际问题

此时,在Google之前的集成中,该脚本最多需要运行一秒钟。它非常令人印象深刻,至少我是这么认为的(服务器,而不是我的编码)。但测试中的谷歌是SLOOOOW。我们可以解决这个问题,但它提出了更大的问题......

在用户确认数据库已更新后,卸载部分工作的最佳方法是什么?这是他最关心的部分,也是最关键的部分。电子邮件通知和Google日历更新只是为了受上传影响的人的利益,如果这些通知出现问题,他会听到它(然后我会听到它),无论脚本告诉谁他是第一个。

例如,有没有办法运行由脚本上次执行触发的cronjob? PHP可以创建具有exec()能力的cronjobs吗?是否有一些标准化的方法来处理需要完成的执行后工作?

对此的任何建议都非常感谢。我觉得脚本臃肿,反映了我的发展阶段,也让我最终知道如何在网络应用中进行分工。

但是我也担心这没有完成,因为用户需要知道所有任务何时完成等等。所以这就出现了:

最佳做法/更主观的问题

基本上,有一个想法是进度条,实时卸载以及其他将用户限制在脚本中的方法 - 当然,当代码优化结合时 - 更好,更优先方法然后简单地说“我们已完成你的部分,如果你需要我们,我们将通知用户”等等。

是否有任何可以避免的事情(除了显然没有给用户任何反馈)?

感谢阅读。编码部分至关重要,因此不要觉得有必要覆盖第二部分或忘记覆盖编码部分!

2 个答案:

答案 0 :(得分:2)

一个cron工作对此有好处。如果用户上传数据时想要做的只是说“嘿用户,感谢数据!”那就没事了。

如果您更喜欢更直接的方法,那么您可以使用exec()来启动后台进程。在Linux环境中,它看起来像这样:

exec("php /path/to/your/worker/script.php >/dev/null &");

&部分说“在背景中训练我。” >/dev/null部分将输出重定向到黑洞。至于处理所有错误并通知相关方 - 这完全取决于您的工作脚本的设计。

要获得更灵活的跨平台方法,请查看此PHP Manual post

答案 1 :(得分:1)

有很多方法可以解决这个问题。您可以像上面所说的那样执行exec(),但如果提交点击次数过多,您可能会遇到DoS情况。 pcntl扩展可以更好地管理这样的流程。查看this post以查看讨论(共有3个部分)。

您可以使用Javascript发送第二个ajax帖子,然后运行相应的工作脚本。通过使用ignore_user_abort()并发送Content-Length,浏览器可以尽早断开连接,但您的apache进程将继续运行并处理您的数据。上行没有叉炸弹潜力,下行可能会开启更多的apache流程。

另一种选择是在后台使用一个cron来查看进程队列表以便“以后”执行操作 - 将项目粘贴到前端的此表中,在处理时将其移除到后端(请参阅Zend_Queue)。

另一种方法是使用更加分散的作业框架,如gearmand - 可以处理其他机器上的项目。

这完全取决于您的整体能力和要求。