我有一台运行在rackspace上的服务器,它托管一个PHP Web应用程序.
PHP Web应用程序将接受表单提交,然后需要根据表单字段条目执行任务.
任务(让我们称之为生成元数据任务)需要相当多的处理时间.我想知道如何允许表单提交直接保存到数据库,并在后台运行生成元数据任务时立即向用户显示成功页面.
我已将"aws/aws-sdk-php": "~3.11"
使用composer 安装到同一个Web应用程序中.
我的计划最初是这样的:
处理表单提交的代码
$result = $model->save($_POST); // this code will send the information to either SQS or SNS $awsClient->sendsMessage($_POST); if ($result) { $this->redirect('success.html'); }
我已经阅读了AWS 所述的扇出架构.
我对扇出架构示例的问题(据我所知)是这样的:
将消息发送到SQS或SNS的服务器也将是处理生成元数据任务的同一服务器.事实上,它是相同的网络应用程序.
SQS完成队列部分(因为我想在FIFO中执行任务,并且任务需要很长时间才能完成).但是,它需要我的网络应用程序连续轮询SQS.我想要一个推送通知(从AWS到我的网络应用程序),而不是我的网络应用程序不断轮询AWS以检查要执行的任务.
我在这里找到了可能的解决方案
建议的解决方案是:
将消息发送到SNS主题.
SNS主题将同时发送SQS队列和我的Web应用程序.
我的Web应用程序在被触发后将轮询同一个SQS队列,该队列现在已连续排队消息,直到队列为空
我从中看到的缺点是我的Web应用程序将在队列本身有消息之前轮询队列.
使用AWS服务实现推送队列的最佳方法是什么?
我的网络应用程序将在队列本身有消息之前轮询队列
那你没试过,对吗?:)我担心你会过度思考这个问题.SQS具有长轮询,这导致轮询请求在SQS侧暂停,直到至少有一条消息可用,此时将返回该消息(最多为您请求的最大数量).您可以将长轮询等待时间设置为1到20秒.如果在此时间范围内没有可用消息,则返回响应而不显示任何消息.
如果您轮询队列以响应来自SNS的通知,那么如果您使用长轮询,则会在那里找到消息.它的邮件可能会被推迟,但非常不可能的.
但另一个问题是你断言你不希望应用程序不断轮询SQS.我经常遇到这种反对意见,而且往往是错位的.使用SQS长轮询,"不断"轮询空队列意味着每20秒进行一次请求.这是3 req/minute,180 req/hour,4320 req/day,129600 req/month ......结果是每月少于100万免费请求.
服务器对通知作出反应而不是在后台使用适当数量的工作人员轮询队列的问题是,您可能很容易被大量同时到达的大量作业所淹没.如果你得到10个并发请求,你能处理吗?100?1000?通常,对于像这样异步的作业,请求作业的成本(执行资源)比执行作业的成本要少(例如,上传图像所需的CPU要比调整图像所需的CPU少得多).除非你协调你的反应反应,否则你可能会压倒你的系统.
不要陷入"轮询不好,推动好"的概念陷阱,因为它不适用.在绝大多数情况下,这种情绪绝对正确......轮询几乎总是错误的解决方案......但是使用SQS长轮询,你真正拥有的是一种推送机制,其方式与HTTP兼容,以及民意调查的大部分内在......都消失了.如果您正处于长轮询中,队列为空,并且消息到达,您的长轮询将几乎立即返回该消息.它不会等待超时发生.观察队列的后台进程可能是一个很好的方法.