AWS SQS 异步排队模式 (Request/Response)
AWS SQS Asynchronous Queuing Pattern (Request/Response)
我正在寻求有关产品架构设计决策的帮助。
我们有多个生产者(由 API 网关调用 Lambda 启动)将消息放入 SQS 队列(请求队列)。可以有多个同时调用,因此会有多个 Lambda 实例 运行 并行。
然后我们有消费者(假设有 20 个 EC2 实例)在 SQS 上长时间轮询消息以处理它们。他们每处理一条消息大约需要 30-45 秒。
理想情况下,我希望将响应发送回发出请求的生产者 - 这是我在使用 SQS 时遇到的问题。理论上我会有一个单独的响应队列,最初的 Lambda 生产者随后会使用它,但似乎没有办法挑选特定的相关响应。也就是说,每个 Lambda 函数都可能获取另一个函数的响应。我正在寻找类似于此设计模式的东西:http://soapatterns.org/design_patterns/asynchronous_queuing
我能看到的唯一选择是为每个 Lambda API 调用创建一个新的 SQS 响应队列,在消息中传递其 ARN 供消费者放置响应,但我不能'想象一下这是非常有效的——尤其是当每分钟可能有数百条消息时?我错过了一些明显的东西吗?
我想唯一的其他选择是设置更大的消息代理(例如 RabbitMQ/ApacheMQ)环境,但我想尽可能避免这种情况。
谢谢!
是的,您可以使用 RabbitMQ 获得更多 "rpc" 队列模式。
但如果您想留在 AWS 中,请尝试使用 SQS 以外的其他方式进行响应。
相反,您可以使用 S3 进行响应。当您的生产者将项目放入 SQS 时,在消息中包含响应的 S3 目标。当您的消费者完成任务时,将响应放在所需的 S3 位置。
然后您可以检查 S3 的响应。
更新
您也许可以使用 Redis 完成类似 RPC 的消息队列。
https://github.com/ServiceStack/ServiceStack/wiki/Messaging-and-redis
然后,您可以将 AWS ElastiCache 用于您的 Redis 集群。这将完全取代 SQS 的使用。
为每个请求创建一个(临时)响应队列
聚会迟到了,但我在想我可能会在我想要实现的目标上找到一些帮助,@MattHouser @Zaheer Ally,或者给从事相关问题的人一个想法。
我也面临着类似的挑战。我有一个 API,根据客户的要求,需要与多个外部 API 通信并收集(延迟的)结果。
由于我的PHPAPI是同步的,所以只能依次执行这些请求。因此,我正在考虑使用 请求队列 ,生产者 (API) 将在其中发送消息。然后,多个工作人员将使用这些消息,每个工作人员执行这些外部 API 调用之一。
为了返回结果,生产者会创建一个临时响应队列,其名称标识符将嵌入到发送给工作人员的消息中。因此,每个工作人员都会'publish'他在这个临时队列中的结果。
与此同时,生产者会不断轮询临时队列,直到收到预期数量的消息。最后,他会删除队列并将收集到的结果发送回客户端。
另一种选择是将 Redis pub/sub mechanism to asynchronously notify your lambda that the backend work is done. You can use AWS's Elasticache for Redis 用于全 AWS 托管解决方案。您的 lambda 函数将为每个请求生成一个 UUID,将其用作要订阅的频道名称,在 SQS 消息中传递它,然后后端工作人员将在工作完成时向该频道发布通知。
我遇到了同样的问题,所以 I tried it out, and it does work. Whether it's worth the effort over just polling S3 is another question. You have to configure the lambda functions to run inside your VPC,所以他们可以访问您的 Redis。无论如何我都必须这样做,因为我希望工作人员(在我的例子中也是 lambda 函数)能够访问我的 Elasticsearch 和 RDS。但有一些注意事项:最重要的是,您需要使用带有 NAT 网关(或您自己的 NAT 实例)的私有子网,以便它可以连接到 Internet 和 AWS 托管服务(包括 SQS)。
我刚刚偶然发现的另一件事是,目前通过 API 网关的请求 cannot take longer than 29 seconds,而 AWS 无法增加这一点。您提到您的作业需要 30 秒或更长时间,所以这对于您以这种方式使用 API Gateway 和 Lambda 来说可能是一个阻碍。
AWS 现在提供 Java client that supports temporary queues。这对于 request/response 模式很有用。我看不到非 Java 版本。
我正在寻求有关产品架构设计决策的帮助。
我们有多个生产者(由 API 网关调用 Lambda 启动)将消息放入 SQS 队列(请求队列)。可以有多个同时调用,因此会有多个 Lambda 实例 运行 并行。
然后我们有消费者(假设有 20 个 EC2 实例)在 SQS 上长时间轮询消息以处理它们。他们每处理一条消息大约需要 30-45 秒。
理想情况下,我希望将响应发送回发出请求的生产者 - 这是我在使用 SQS 时遇到的问题。理论上我会有一个单独的响应队列,最初的 Lambda 生产者随后会使用它,但似乎没有办法挑选特定的相关响应。也就是说,每个 Lambda 函数都可能获取另一个函数的响应。我正在寻找类似于此设计模式的东西:http://soapatterns.org/design_patterns/asynchronous_queuing
我能看到的唯一选择是为每个 Lambda API 调用创建一个新的 SQS 响应队列,在消息中传递其 ARN 供消费者放置响应,但我不能'想象一下这是非常有效的——尤其是当每分钟可能有数百条消息时?我错过了一些明显的东西吗?
我想唯一的其他选择是设置更大的消息代理(例如 RabbitMQ/ApacheMQ)环境,但我想尽可能避免这种情况。
谢谢!
是的,您可以使用 RabbitMQ 获得更多 "rpc" 队列模式。
但如果您想留在 AWS 中,请尝试使用 SQS 以外的其他方式进行响应。
相反,您可以使用 S3 进行响应。当您的生产者将项目放入 SQS 时,在消息中包含响应的 S3 目标。当您的消费者完成任务时,将响应放在所需的 S3 位置。
然后您可以检查 S3 的响应。
更新
您也许可以使用 Redis 完成类似 RPC 的消息队列。
https://github.com/ServiceStack/ServiceStack/wiki/Messaging-and-redis
然后,您可以将 AWS ElastiCache 用于您的 Redis 集群。这将完全取代 SQS 的使用。
为每个请求创建一个(临时)响应队列
聚会迟到了,但我在想我可能会在我想要实现的目标上找到一些帮助,@MattHouser @Zaheer Ally,或者给从事相关问题的人一个想法。
我也面临着类似的挑战。我有一个 API,根据客户的要求,需要与多个外部 API 通信并收集(延迟的)结果。
由于我的PHPAPI是同步的,所以只能依次执行这些请求。因此,我正在考虑使用 请求队列 ,生产者 (API) 将在其中发送消息。然后,多个工作人员将使用这些消息,每个工作人员执行这些外部 API 调用之一。
为了返回结果,生产者会创建一个临时响应队列,其名称标识符将嵌入到发送给工作人员的消息中。因此,每个工作人员都会'publish'他在这个临时队列中的结果。
与此同时,生产者会不断轮询临时队列,直到收到预期数量的消息。最后,他会删除队列并将收集到的结果发送回客户端。
另一种选择是将 Redis pub/sub mechanism to asynchronously notify your lambda that the backend work is done. You can use AWS's Elasticache for Redis 用于全 AWS 托管解决方案。您的 lambda 函数将为每个请求生成一个 UUID,将其用作要订阅的频道名称,在 SQS 消息中传递它,然后后端工作人员将在工作完成时向该频道发布通知。
我遇到了同样的问题,所以 I tried it out, and it does work. Whether it's worth the effort over just polling S3 is another question. You have to configure the lambda functions to run inside your VPC,所以他们可以访问您的 Redis。无论如何我都必须这样做,因为我希望工作人员(在我的例子中也是 lambda 函数)能够访问我的 Elasticsearch 和 RDS。但有一些注意事项:最重要的是,您需要使用带有 NAT 网关(或您自己的 NAT 实例)的私有子网,以便它可以连接到 Internet 和 AWS 托管服务(包括 SQS)。
我刚刚偶然发现的另一件事是,目前通过 API 网关的请求 cannot take longer than 29 seconds,而 AWS 无法增加这一点。您提到您的作业需要 30 秒或更长时间,所以这对于您以这种方式使用 API Gateway 和 Lambda 来说可能是一个阻碍。
AWS 现在提供 Java client that supports temporary queues。这对于 request/response 模式很有用。我看不到非 Java 版本。