2

第一的,

设置:

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

本节特意啰嗦一句。如果您不喜欢,请跳过

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

现在我可能正在添加一个谷歌日历 API,它将数据(当它是调度数据时)发布到用户的谷歌日历。我会通过他们的工作日历来完成,但我想在处理为 Exchange 设置 WebDav 系统之前,我会先接触 Google 的 API。

</backstory>

现在!

实际问题

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

在用户确认数据库已更新后,卸载一些工作的最佳方法是什么?这是他最关心的部分,也是最关键的部分。电子邮件通知和 Google 日历更新仅适用于受上传影响的人,如果这些通知有问题,他会听到(然后我会听到),不管脚本告诉他先。

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

对此的任何建议都非常感谢。我觉得脚本臃肿反映了我的开发阶段以及我最终知道如何在 Web 应用程序中进行分工的需要。

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

最佳实践/更主观的问题

基本上,是否有这样一种想法,即进度条、实时卸载和其他让用户与脚本保持联系的方法——当然,当与代码优化相结合时——是更好、更受欢迎的方法,然后简单说“我们已经完成了你的工作,如果你需要我们,我们会通知用户”等等。

是否有什么大事要避免(除了显然根本不给用户任何反馈)?

谢谢阅读。编码部分至关重要,所以不要觉得有义务覆盖第二部分或忘记覆盖编码部分!

4

2 回答 2

2

一个 cron 工作对此有好处。如果您在用户上传数据时只想说“嘿,用户,感谢您提供数据!” 那么这会很好。

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

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

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

如需更灵活的跨平台方法,请查看此PHP 手册帖子

于 2009-10-11T03:24:53.957 回答
1

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

您可以使用 Javascript 发送第二个 ajax 帖子,然后运行相应的工作脚本。通过使用 ignore_user_abort() 并发送 Content-Length,浏览器可以提前断开连接,但您的 apache 进程将继续运行并处理您的数据。优点是没有分叉炸弹的潜力,缺点是它将打开更多的 apache 进程。

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

还有一个是使用更分布式的作业框架,如gearmand - 它可以处理其他机器上的项目。

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

于 2009-10-19T00:35:04.257 回答