amazon-web-services - 如何在分布式系统中仅发送一次电子邮件

标签 amazon-web-services distributed distributed-computing distributed-transactions

我有一个这样的系统:

  • 节点从队列中读取事件。
  • 使用 AWS SES 根据事件发送通知电子邮件。

可能出现问题的情况是:

  1. 其他一些节点也可能并行读取事件的重复副本,因此现在发送了 2 封电子邮件。

  2. 节点 1 读取事件,发出“发送电子邮件”调用,然后在未确认已发送电子邮件的情况下死亡。节点1不知道邮件是否已发送,因此恢复后会重新发送。

如何确保电子邮件仅发送一次?

最佳答案

我相信大多数现代排队系统通常都能处理场景 1。我认为还有其他问题可以更好地解决此类锁定问题,因此我暂时忽略它。

关于场景 2,大多数现代排队系统都会处理相同的问题 - 它基本上归结为一个关于您希望如何失败的问题。

例如,如果您必须在发送电子邮件两次或不发送电子邮件之间做出选择,您会选择哪一个?用队列术语来说,这被描述为“至少一次”与“最多一次”交付。

对于这些答案,我假设像 RabbitMQ 这样的排队系统可以启用确认和超时。

选项 1 - 发送电子邮件两次 尝试发送电子邮件,如果成功,则将消息确认到队列中。设置队列,以便在超时后重新添加未确认的消息。在这种情况下,如果发送过程中发生故障,则不会发生ack,并且消息将被重新发送到队列中,然后再次被拾取。现在,如果确认(但不是您的电子邮件)持续失败,您最终可能会遇到继续发送电子邮件的情况。然而,大多数时候,这应该不是问题。

选项 2 - 不发送电子邮件 设置一个没有 ack 的队列。这通常性能更高,所以这是一个优点。队列工作人员将从队列中获取消息并尝试发送电子邮件。如果电子邮件发送失败,则不会重试。

对于我从事的许多服务(这不适用于电子邮件,但适用于写入数据库),我尝试使它们具有幂等性,然后选择第一个选项。在最坏的情况下,您会进行写入操作,但希望您有日志记录来检测这一点。

关于amazon-web-services - 如何在分布式系统中仅发送一次电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35075632/

相关文章:

java - 用于在 SOA 环境中实现请求-响应类型应用程序的框架/协议(protocol)/工具

amazon-web-services - AWS 云信息 : Cross Stack Reference

amazon-web-services - Athena Presto 中 array_agg 的长度限制

tensorflow - 使用 Keras 中的分布式学习在多个 GPU 上分配大张量

MongoDB 无共享奴隶

database - 通过分布式数据库聚合作业优化网络带宽

java - AWS Java SDK - AWS 身份验证需要有效的 Date 或 x-amz-date header

amazon-web-services - 如何在AWS API Gateway中传递查询字符串参数?

Erlang:如何查看远程节点上产生的进程中 io:format/2 调用的输出

configuration - Microsoft Orleans 每个筒仓的最大颗粒数