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

时间:2016-01-29 02:00:28

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

我有一个这样的系统:

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

可能出现问题的情况包括:

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

  2. 节点1读取事件,发送电子邮件'在没有确认发送的电子邮件的情况下打电话然后死节点1不知道电子邮件是否已发送,因此在重新启动后会重新发送。

  3. 我如何确保只发送一次电子邮件?

1 个答案:

答案 0 :(得分:1)

我认为情景1通常由大多数现代排队系统处理。我认为还有其他问题可以更好地解决锁定问题,所以我暂时忽略它。

关于方案2,大多数现代排队系统都处理同样的问题 - 它基本上归结为一个关于你想如何失败的问题。

例如,如果您必须选择两次发送电子邮件或不发送电子邮件,您会选择哪种?在队列用语中,这被描述为至少一次与最多一次交付。

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

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

选项2 - 不提供电子邮件 设置一个没有确认的队列。这通常更高效,所以这是一个优点。队列工作人员将从队列中接收消息并尝试发送电子邮件。如果电子邮件无法发送,则不会重试。

对于我工作的许多服务(这不适用于电子邮件,但确实适用于写入数据库),我尝试使它们具有幂等性,然后只使用第一个选项。在最糟糕的情况下,你会改变写入,但希望你有记录来检测它。