AWS SQS异步排队模式(请求/响应)

问题描述 投票:4回答:3

我正在寻找有关我用产品制作的建筑设计决策的帮助。

我们有多个生成器(由API Gateway调用Lambda启动)将消息放在SQS队列(请求队列)上。可以有多个同时调用,因此会有多个并行运行的Lambda实例。

然后我们让消费者(比如二十个EC2实例)在SQS上长时间轮询消息来处理它们。他们每个处理一条消息大约需要30-45秒。

然后,我最好将响应发送回发出请求的制作人 - 这是我正在与SQS斗争的部分。理论上我会有一个单独的响应队列,最初的Lambda生产者会消耗,但似乎没有办法挑选特定的相关响应。也就是说,每个Lambda函数可能会获取另一个函数的响应。我正在寻找类似于这种设计模式的东西:http://soapatterns.org/design_patterns/asynchronous_queuing

我能看到的唯一选择是为每个Lambda API调用创建一个新的SQS响应队列,在消息中传入其ARN以供消费者使用,但我无法想象这是非常有效的 - 特别是当有可能每分钟有数百条消息?我错过了一些明显的东西吗

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

谢谢!

amazon-web-services aws-lambda amazon-sqs
3个回答
2
投票

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

但是,如果您想留在AWS中,请尝试使用SQS之外的其他内容进行响应。

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

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

更新

您可以使用Redis完成类似RPC的消息队列。

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

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


2
投票

另一种选择是使用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)。

我偶然发现的另一件事是通过API Gateway目前cannot take longer than 29 seconds的请求,这不能通过AWS增加。您提到您的工作需要30秒或更长时间,因此无论如何,这可能是您使用API​​ Gateway和Lambda的一个showstopper。


1
投票

为了晚会,但我想我可能会找到一些我想要实现的帮助,@ MaiHouser @Zaheer Ally,或者向一个相关问题的人提出一个想法。

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

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

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

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

虽然看起来是正确的,但我觉得这个解决方案根本不优雅,容易出现故障,而且对于用PHP实现的典型HTTP请求 - 响应周期来说效率肯定不高。

有什么想法吗?

© www.soinside.com 2019 - 2024. All rights reserved.