我有一台在机架空间上运行的服务器,它托管一个 PHP Web 应用程序。
PHP Web 应用程序将接受表单提交,然后需要根据表单字段条目执行任务。
该任务(我们将其称为生成元数据任务)需要相当多的处理时间。我想知道如何允许表单提交直接保存到数据库,并在后台运行生成元数据任务时立即向用户显示成功页面。
我已经安装了"aws/aws-sdk-php": "~3.11"
在同一个 Web 应用程序中使用 Composer。
我的计划最初是这样的:
处理表单提交的代码
$result = $model->save($_POST);
// this code will send the information to either SQS or SNS
$awsClient->sendsMessage($_POST);
if ($result) {
$this->redirect('success.html');
}
我读过有关扇出架构 http://docs.aws.amazon.com/sns/latest/dg/SNS_Scenarios.htmlAWS 表示。
我对扇出架构示例的问题(据我所知)是这样的:
- 将消息发送到 SQS 或 SNS 的服务器也将是处理生成元数据任务的同一服务器。事实上,这是同一个网络应用程序。
- SQS 完成队列部分(因为我想执行 FIFO 中的任务,并且任务确实需要很长时间才能完成)。但是,它需要我的网络应用程序不断轮询 SQS。我想要推送通知(从 AWS 到我的 Web 应用程序),而不是我的 Web 应用程序不断轮询 AWS 以检查要执行的任务。
我找到了建议的可能解决方案here http://forecastcloudy.net/2011/07/12/using-amazons-simple-notification-service-sns-and-simple-queue-service-sqs-for-a-reliable-push-processing-of-queues/
建议的解决方案是:
将消息发送到 SNS 主题。
SNS 主题将向 SQS 队列和我的 Web 应用程序发送消息。
我的网络应用程序被触发后,将轮询现在已连续排队消息的同一个 SQS 队列,直到队列为空
我从中看到的缺点是我的网络应用程序将在队列本身有消息之前轮询队列。
使用 AWS 服务实施推送队列的最佳方法是什么?
我的网络应用程序将在队列本身有消息之前轮询队列
那你还没试过吧? :) 恐怕你想太多了。 SQS 有长轮询,这会导致轮询请求在 SQS 端挂起,直到至少有一条消息可用,此时将返回该消息(最多可达您请求的最大数量)。您可以将长轮询等待时间设置为 1 到 20 秒。如果在此时间范围内没有可用的消息,则返回不带消息的响应。
如果您响应来自 SNS 的通知而轮询队列,您will如果您使用长轮询,则可以在那里找到消息。消息可能会延迟,但是highly不太可能。
不过,另一个问题是您断言您不希望应用程序不断轮询 SQS。我经常遇到这种反对意见,而且它常常是错误的。对于 SQS 长轮询,“持续”轮询空队列意味着每 20 秒一次请求。即 3 个请求/分钟、180 个请求/小时、4320 个请求/天、129600 个请求/月……结果低于每月允许的 100 万个免费请求。
服务器对通知做出反应而不是在后台使用适当数量的工作人员轮询队列的问题是,您可能很容易被大约同时到达的大量作业淹没。如果你有10个并发请求,你能处理吗? 100? 1000?通常,对于像这样的异步作业,请求作业的成本(就资源而言)比执行作业的成本要低(例如,上传图像所需的 CPU 比调整图像大小所需的 CPU 少得多)。除非你协调你的反应,否则你的系统可能会不堪重负。
不要陷入“轮询不好,推送好”的概念陷阱,因为它不适用。绝大多数时候,这种观点是绝对正确的...轮询几乎总是错误的解决方案...但是通过 SQS 长轮询,您真正拥有的是一种以与 HTTP 兼容的方式包装的推送机制,并且民意调查的许多固有的邪恶......消失了。如果您正在进行长轮询,队列为空,并且有消息到达,则您的长轮询将几乎立即返回该消息。它不会等待超时发生。毕竟,监视队列的后台进程可能是一个好方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)