我父亲想建立一个时事通讯发送系统,作为定制系统的一部分,提供自定义字段。用户可以在文本中使用一些特殊变量来插入收件人的姓名(以及其他内容)。
最后一个要求电子邮件中所有数据的HTML表单会将数据以及收件人集插入数据库。然后,用户被重定向到辅助角色脚本。
在worker脚本(我们称之为worker.php
)中,他大致有以下内容:
# Get current job from the database.
# Pop off the first recipient in the list.
# Retrieve additional data about that recipient from the database.
# Generate and send email.
# Store truncated list of recipients in database.
if (work_left) {
header('Location: worker.php');
}
else {
header('Location: done.php');
}
worker只做一个工作项来躲避PHP的时间限制。该系统将部署在可能具有最神秘php.ini
设置的共享主机上。
它有效,处理工作项,数据库中的收件人数量减少。现在不可预见的问题是浏览器最终超时,取消连接。然后取消 PHP 脚本,不再执行任何工作。通过将浏览器指向worker.php
可以轻松重新启动该过程,但这是最终用户不必做的事情。
在这个网站上快速搜索给了我ignore_user_abort
功能,它看起来很有希望,以避免浏览器超时。我担心这并不能解决这种情况下的问题:浏览器会在某个时候关闭连接。当前运行的 PHP 脚本将完成运行,然后告诉浏览器重新加载worker.php
。浏览器不再侦听,进度也停止。这是一项改进,因为它不会在交易中停止,但不是解决方案。
我们的另一个想法是将重定向替换为一个到worker2.php
。该PHP文件仅包含重定向回worker.php
。这对浏览器来说可能是足够的进度,它将继续加载而不会碰到超时(希望超时至少是每个 URL?
如果这也不起作用,那么带有<meta>
的 HTML 重定向可能是另一种选择。然后,worker.php
将实际完成加载,浏览器将能够完成请求。然后,<meta>
将再次重定向到worker.php
以执行下一个工作项。最后一个缺点是它仍然取决于要打开的浏览器。
在最好的情况下,他正在寻找一个解决方案,一旦启动,它就会贯穿始终。浏览器可能会超时,用户可以关闭窗口,脚本仍将运行并发送所有电子邮件。是否可以生成一个不受 PHP 执行时间限制和浏览器超时影响的工作线程?
也许与其依赖共享主机上的花哨背景脚本,不如使用 crontab(即使您的托管服务提供商没有给您一个您可以使用一些允许您模拟 cron 的服务),它将每分钟触发一次脚本(?脚本将检查队列表中是否有一些工作,选择一些(在您的服务器允许您处理的范围内)并将已处理的任务标记为已完成(或将它们从表中删除)。然后,您可以提供一些端点,发件人可以访问该端点以查看其进度(计算用户的所有任务和标记为已完成的任务)。我不认为你能在分片上使用RabbitMQ + supervisord或类似的东西,但我不认为使用后台php脚本是好主意:)