【发布时间】:2022-06-14 16:26:25
【问题描述】:
我开发了一个用于发送大量电子邮件的服务(在 .net 中)
服务可以在多个节点上执行
我在 MongoDB 中有一个包含所有电子邮件数据的集合,我如何在其他节点不读取的情况下读取节点上的数据?
我想避免多次发送同一封邮件
【问题讨论】:
我开发了一个用于发送大量电子邮件的服务(在 .net 中)
服务可以在多个节点上执行
我在 MongoDB 中有一个包含所有电子邮件数据的集合,我如何在其他节点不读取的情况下读取节点上的数据?
我想避免多次发送同一封邮件
【问题讨论】:
基本上,您需要通知其他节点文档已在处理中。因此,您可以在文档中添加标记属性,例如:
public class MyDocument
{
// ... other members
// I suppose there is some kind of status property on the document
public bool Done { get; set; }
public DateTime? StartedProcession { get; set; }
}
为什么这是DateTime? 属性?因为这样可以处理节点在发送邮件和更新状态标志时遇到的错误。
您可以使用 MongoDB 的 FindAndModify 方法来识别节点应该发送的下一封邮件。此方法仅找到一个文档并对其执行原子更新。条件是:
更新应将StartedProcession 属性设置为当前时间。这样,其他节点就不会尝试发送相同的邮件了。
在节点中,发送邮件。如果一切顺利,您更新文档上的Done 标志;如果没有,您可以将StartedProcession 属性重置为 null 以允许重试(此外,您还可以将错误详细信息存储在文档中以供以后分析)。
如果发生灾难性错误,节点不会重置StartedProcession 属性,上面的过滤器会断言另一个节点将在一小时后重试传输。
请注意,在极少数情况下,邮件可能仍会发送两次,例如如果邮件发送成功,但Done 标志更新失败。但是,这应该是非常罕见的,因为FindAndModify 第一步进展顺利,并且在执行更新后几毫秒。
【讨论】: