amazon-web-services - 在 SQS lambda 环境中扇出的推荐方法是什么?

标签 amazon-web-services aws-lambda architecture amazon-sqs serverless-framework

我想通过 SQS/消息队列架构在 lambda 环境中向我的数据库中的用户发送推送通知,以实现这一点

  1. 我首先需要在启用推送通知的情况下查询我的数据库中的所有用户。
  2. 遍历所有这些
  3. 为每个用户发送 SQS 事件/消息。
  4. 让我的 sqs 触发 lambda 处理/发送推送通知

是否有更好的方法来实现此目的以避免查询大量用户和/或遍历所有结果来为每个结果发送 SQS 消息?

最佳答案

我会在这里采用稍微不同但相似的方法。

  1. 为用户查询数据库
  2. 遍历用户
  3. 发送一条消息给SQS,让一批记录发送,使用SQS的SendMessageBatch操作发送。所以一批一批的。每批消息将有多个“用户”发送给,而不仅仅是一个。这将提高您的性能,因为批处理将需要更少的 lambda 调用。
  4. Lambda 处理 SQS 消息(可能不止一条),每条 SQS 消息都会发送许多推送通知。就 Firebase 而言,我相信有一种发送批处理的方法,这种方法更好。即使没有它,您也可以使用 Promise.all 类型逻辑一次发送多条消息。

使用这种结构,您可以非常快速地发送大量消息,而且可能会便宜很多。想象一下,您需要发送给 100 万用户。如果您将 100 个批处理发送到 SQS,每批处理发送 25 个,那么每次调用 SQS 都会有 2,500 条消息。这意味着对 SQS 的 400 次调用,甚至比以 25 条为一组发送单条消息时必须进行的 40K 调用要好得多。

在接收方,即使您将 SQS 集成限制为每次调用 1 条消息,您也会有 10,000 次 lambda 调用。如果您假设每次调用甚至 1 秒,并且有 1000 个并发调用,则需要 10 秒(可能更少)。如果您向每位用户发送一条消息,则您必须进行 1M 次 lambda 调用。如果您假设每次调用需要 100 毫秒,那么您可以每秒发送 10 次,因此 1000 次并发执行将需要 100 秒。实际上,这些数字可能比批处理版本的数字还要好,特别是如果您不将它一次限制为 1 条消息。

编辑 根据评论,问题似乎更多地与流程的第一部分有关。考虑到这一点,我建议以下选项。

  1. 如果您发现自己需要重复处理相同的大型群组,大多数消息服务(当然是 Firebase 和 SNS)都支持某种主题订阅模型。鉴于这些是推送通知,您可以在代码中为设备订阅该主题。这最终会导致一条消息从您的代码发送到消息服务。该服务处理其余部分。这可能是任何具有大量收件人的首选解决方案,特别是如果您可以预先知道收件人。这甚至适用于动态主题。例如,考虑一个人对帖子发表评论的情况。对该帖子的任何新评论都应该向对该帖子发表评论的每个人发送一条消息。您可以在创建帖子时即时创建主题,并在收件人发表评论时将他们添加到主题中。如果用户希望停止接收消息,您可以将该用户从主题中删除。
  2. 如果您事先不知道收件人,上述解决方案是一个可靠的解决方案。但是,如果您担心前两个步骤中的 Lambda 超时,我会稍微修改一下。我会利用 AWS Step Functions 并在 lambda 中分页数据。 Lambda 将通过调用中提供的 context 对象告诉您剩余时间。您可以定期检查以确定是否应该退出 lambda 并将当前分页信息传递给 step 函数。 step 函数可以将该分页信息传递回 lambda,lambda 应该被编码为接受分页信息作为请求的一部分,并从该点继续(如果提供)。

关于amazon-web-services - 在 SQS lambda 环境中扇出的推荐方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60150356/

相关文章:

amazon-web-services - Amazon S3 Glacier 存储与直接使用 Amazon Glacier 服务相同吗?

python - 更新 DynamoDB 时出现客户端错误?

Spring Cloud Function-适合REST API吗?如何访问 GET 路径参数?

amazon-web-services - 将 CloudFront 主机 header 转发到 API 网关

android - 在 Android 中添加 "splits"后出现错误 : Could not find EOCD,

amazon-web-services - 我可以将另一个文件中的文本插入到我的 cloudformation 模板中吗?

javascript - 在生产中将 header 发送到客户端后无法设置 header

php - 大于 bigint 的 MySQL 字段

c - 服务器架构之谜,C编程

amazon-web-services - 使用目标触发器从 Lambda 到 SQS 的多条消息