2

我有一个这样的系统只发送一次电子邮件:如何在分布式系统中

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

这里的问题可能出现的情况是:

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

  2. 节点1读取的情况下,使得“发送电子邮件”呼叫,然后不承认在发送的电子邮件死亡。节点1不知道电子邮件是否被发送,所以在回来后重新发送。

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

+0

你正在使用什么类型的队列?大多数现代排队系统都应该有助于情景1,至少您可以设置最多一次的送货。此外,您可能必须在至多一次或至少一次之间进行选择。你会选择哪种方案? – patwhite

+1

这个问题是关于SQS的吗?因为答案会有所不同,具体取决于您使用哪个队列系统以及该系统支持的内容。 –

+0

你可以假设SQS为这个问题 – pdeva

回答

1

我相信方案1通常是由最先进的排队系统来处理。我认为还有其他问题可以更好地解决像这样的锁定问题,所以我暂时忽略它。

关于方案2,最现代化的排队系统处理同样的问题 - 它基本上可以归结为一个关于要如何失败的问题。

举例来说,如果你有提供电子邮件两次或不提供它之间做出选择,你会选择哪个?按照队列的说法,这至少被描述为一次交付。

对于这些问题的答案,我假设一个排队系统类似的RabbitMQ使ACK和超时。

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

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

对于很多,我的工作服务的(这并不适用于电子邮件,但适用于写入到DB),我尽量让他们幂等,然后就一起去的第一个选项。在最糟糕的情况下,你会写道,但希望你有日志记录来检测这个。