在发送到 SNS 之前,我可以使用 Amazon SQS 作为延迟队列吗?

Posted

技术标签:

【中文标题】在发送到 SNS 之前,我可以使用 Amazon SQS 作为延迟队列吗?【英文标题】:Can I use Amazon SQS as a delay queue before sending to SNS? 【发布时间】:2015-11-27 14:15:30 【问题描述】:

我的系统在 Amazon 自动缩放组上运行,其中一项功能允许用户对用户进行消息传递,我需要解决以下用例。

    一条新消息在我的应用程序中的用户之间发送。 通过电子邮件通知用户的消息被放入队列中,延迟 60 秒。此延迟允许实时聊天客户端 (faye/angularjs) 有时间查看消息并将其标记为已查看。 在延迟接收消息后,检查“已读”状态,如果客户端尚未阅读,则发送电子邮件。

最初我打算在每个应用程序服务器上使用 cronjob 来轮询消息队列,但在我看来,使用 SNS 调用某种电子邮件发送端点(可能在 Lambda 中)会更有效。

但是,我看不到任何让 SNS 轮询 SQS 的方法,有人可以建议如何做到这一点吗?本质上,我希望 SNS 有延迟,这样我就不会在带有电子邮件警报的“实时”聊天中向某人发送垃圾邮件。

谢谢

【问题讨论】:

【参考方案1】:

不幸的是,这还不是开箱即用的。缺少的部分是由Amazon SQS 队列生成Amazon SNS 消息到达/可见性通知,无论是通过推送(类似于Amazon S3 notifications,还是通过类似于Amazon Kinesis subscriptions 的轮询(有关更多信息,请参阅The Pull/Push Event Models区别),这两者都允许将AWS Lambda 函数直接连接到相应的SQS delay queue 事件,参见例如:

Lambda with SQS

话虽如此,您可以通过几种方式解决此限制,例如:

按计划触发您的 Lambda 函数(例如每分钟一次),并从那里轮询您的 SQS 延迟队列 计划的 Lambda 函数反过来是 eagerly awaited missing Lambda feature,但它更容易解决,无论是通过您的 cron 工作,还是 Eric Hammond 的 Unreliable Town Clock (UTC),例如

AWS Lambda 团队在最近一个月提交了许多/最相似的功能请求。顺便说一句。所以我希望他们在一年中仍然提供 SQS 事件处理和计划的 Lambda 函数。

【讨论】:

听起来我现在最好采取 cronjob-listening-to-SQS 路线。直到亚马逊推出一些附近的功能!谢谢! 对于那些在 2017 年或之后发现自己的人 - 查看 Amazon 的“云 cron”解决方案:CloudWatch Events:docs.aws.amazon.com/AmazonCloudWatch/latest/events/…【参考方案2】:

在 2019 年初,这个问题可以通过几种不同的方式解决:

SQS as an Event Source to Lambda(最终于2018-06-28公布), 类似于 OP 的原始设计。

AWS Step Functions(2016-12-01 宣布),使用等待步骤 延迟。

DynamoDB Streams with Lambda triggers(2017-02-17 公布), 使用项目的 TTL 过期来触发 Lambda 触发器。

由于 SNS 有 topic limit of 100,000 per account,我建议使用 Amazon SES 发送电子邮件(每月 62,000 封免费电子邮件可以帮助决定实施成本)。

【讨论】:

以上是关于在发送到 SNS 之前,我可以使用 Amazon SQS 作为延迟队列吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node JS 中使用 Amazon SNS 向 iOS 设备发送 VoIP 推送通知

Amazon SNS 静默推送

使用 Amazon SNS 服务发送推送通知

如何在一次 API 调用中通过 Amazon SNS 发送推送通知?

将 Amazon SNS 与 React Native 结合使用

未收到来自 Amazon SNS 的 GCM 推送通知