我开发了一个服务(在。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
方法来确定节点应该发送的下一封邮件。此方法只查找一个文档,并对其执行原子更新。条件为:
- Done is false
- StartedProcession在过去是空的或超过一个小时(或更适合您的需要的值)
更新应该将StartedProcession
属性设置为当前时间。这样,其他节点就不会尝试发送相同的邮件。
在节点中发送邮件。如果一切正常,则更新文档上的Done
标志;如果没有,您可以将StartedProcession
属性重置为null以允许重试(此外,您还可以将错误详细信息存储在文档中以供以后分析)。
如果一个错误是灾难性的,节点没有重置StartedProcession
属性,上面的过滤器断言另一个节点将在一小时后重试传输。
请注意,在一些罕见的情况下,邮件可能仍然被发送两次,例如,如果邮件发送成功,但Done
标志的更新失败。但是,这应该是非常罕见的,因为FindAndModify
在第一步进行得很顺利,并且在执行更新后的几毫秒。