2017-06-20 55 views
1

我正在寻找与我正在使用产品进行的架构设计决策有关的帮助。AWS SQS异步排队模式(请求/响应)

我们已经有多个生产者(由API网关调用到Lambda中发起)将消息放入SQS队列(请求队列)中。可以有多个同时调用,所以会有多个并行运行的Lambda实例。

然后我们有消费者(让我们说20个EC2实例)对SQS进行长时间轮询以处理消息。他们需要大约30-45秒来处理每条消息。

然后,我会理想地将响应发回给发出请求的生产者 - 这是我与SQS一起努力的部分。理论上我会有一个单独的响应队列,最初的Lambda生产者将会消耗这些响应队列,但似乎没有办法选择具体的相关响应。也就是说,每个Lambda函数可能会选择另一个函数的响应。我正在寻找类似于此设计模式的东西:http://soapatterns.org/design_patterns/asynchronous_queuing

我可以看到的唯一选择是为每个Lambda API调用创建一个新的SQS Response队列,并在其消息中传递消息中的ARN对此的回应,但我无法想象这非常有效 - 尤其是当每分钟有数百条消息时?我错过了明显的东西吗?

我想唯一的另一种选择是设置一个更大的消息代理(例如RabbitMQ/ApacheMQ)环境,但是我希望尽可能避免这种情况。

谢谢!

回答

1

是的,你可以使用RabbitMQ来获得更多的“rpc”队列模式。

但是,如果您希望保留在AWS内,请尝试使用除SQS以外的其他内容作为响应。

相反,您可以使用S3作为响应。当您的生产者将该项目放入SQS时,在消息中包含响应的S3目标。当您的消费者完成任务时,将响应放置在所需的S3位置。

然后您可以检查S3的响应。

更新

您可以实现使用Redis的一个RPC般的消息队列。

https://github.com/ServiceStack/ServiceStack/wiki/Messaging-and-redis

然后,您可以使用AWS ElastiCache为您的Redis集群。这将完全取代SQS的使用。

+0

嗨马特,谢谢你的回应。我不确定S3如何在这种情况下工作 - 生产者将不得不轮询以检查S3响应文件是否存在? S3上没有长时间轮询我可以找到,所以即使我每秒都检查一次,它看起来效率很低,特别是每分钟可能有数百个请求。 –

+0

正确,你将不得不轮询S3。 AWS无法向您的Lambda函数反馈回应已准备就绪。所以你有4个选项:(a)使用SQS,每个请求一个队列,(b)使用SQS,共享结果队列(这两个选项都不是理想的),(c)轮询某个结果的东西(S3,数据库等) 。),或(d)使用非AWS服务。 –

+0

再次感谢,我感谢您在此问题上的明确和专业知识。我之前没有使用过Redis,但是你的链接(特别是Request + Reply MQ Pattern)听起来像是一个很好的选择,所以我会调查一下,看看它是否适用于我们的环境。再次感谢。 –

0

为了晚会来临,但我想我可能会在我想达到的目标中找到一些帮助,@MattHouser @Zaheer Ally,或者给某个在相关问题上工作的人提供一个想法。

我正面临类似的挑战。我有一个API,根据客户的请求,需要与多个外部API进行通信并收集(延迟)结果。

由于我的PHP API是同步的,它只能按顺序执行这些请求。所以,我正在考虑使用请求队列,其中生产者(API)将发送消息。然后,多个工作人员会使用这些消息,每个人都执行这些外部API调用之一。

为了得到结果,生产者将创建一个临时响应队列,其名称标识符将嵌入到发送给工人的消息中。因此,每个工人都会在这个临时队列上“公布”他的结果。

与此同时,生产者将继续轮询临时队列,直到他收到预期的消息数量。最后,他会删除队列并将收集到的结果发送回客户端。

虽然看起来是正确的,但我觉得这个解决方案根本不够优雅,容易出现故障,对于在PHP中实现的典型HTTP请求 - 响应周期来说,这种方法绝对没有效率。

有什么想法?

0

另一种选择是使用Redis的'pub/sub机制异步通知您的lambda后端工作已完成。您可以将AWS's Elasticache for Redis用于全AWS管理的解决方案。您的lambda函数会为每个请求生成一个UUID,将其用作订阅的通道名称,并在SQS消息中传递它,然后当工作完成后,后端工作人员会向该通道发布通知。

我正面临同样的问题,所以I tried it out,它确实有效。是否值得仅仅投票S3就是另一个问题。您必须将lambda函数配置为run inside your VPC,以便他们可以访问您的Redis。无论如何,我将不得不这样做,因为我希望工作人员(在我的情况下也是lambda函数)能够访问我的Elasticsearch和RDS。但是有一些注意事项:最重要的是,您需要使用带有NAT网关(或您自己的NAT实例)的私有子网,以便能够访问Internet和AWS托管服务(包括SQS)。我只是偶然发现

aws diagram

的另一件事是,通过API网关目前cannot take longer than 29 seconds,而这种要求不能得到提高AWS。您提到您的工作需要30秒或更长时间,因此无论如何,这可能会成为您使用API​​ Gateway和Lambda的不二人选。