让我说我有一个日历活动:
calendar_event (
id UUID,
start_time timestamp,
end_time timestamp,
...
)
我让用户为这些事件创建通知
notification (
id UUID,
event_id UUID, # the id of the event in calendar_event
notification_time timestamp, # the time the notification should be sent
notification_sent boolean DEFAULT false, # true if the notification has been sent
)
这个应用程序足够用,我有多个节点(例如宁静的Java应用程序)处理创建事件,创建通知和删除通知等,并将该数据存储在某些数据库中,例如MySQL。
并且还假设我按时发送通知非常重要,并且用户能够在不久的将来更新通知。
如何确保每个通知至少发送一次?
我们可以有另一个应用程序,它每分钟轮询一次,然后发送通知,但是如果该应用程序关闭了任何时间,我们将丢失通知。如果我们使用布尔字段将通知标记为已发送,那么我们可以追上,但是可能会迟到。而且,如果我们在下一分钟存储信息,并且删除了一条通知,因此不应该发送通知,那么我们将在不应该发送的时候发送通知。
让我想起了一个队列,但是具有一些不同的属性;我们需要按notification_time排序,而不是插入时间,并且我们需要允许删除。
答案 0 :(得分:1)
如何确保分布式通知至少一次 系统吗?
有很多方法可以实现这一点,但是考虑到您的情况,队列是简单的选择。您的要求是通知可靠性,可以将案例中的消息(通知)发送到多个队列,也可以尝试使用主队列,如果失败,则发送到辅助队列。在读取端,如果从辅助读取失败,则可以尝试使用主队列。另外,您还必须确保队列在不同的硬件/机器等上。通过这种方式,您可以避免硬件故障。取决于您的基础平台,Azure,AWS或Google之类的云平台可以帮助您实现可靠队列的长途之路。
我们需要 按notification_time排序,而不是插入时间,我们需要允许 删除。
在这里,因为您具有“创建通知”的“多个节点”,所以可以使用简单的管道和过滤器体系结构,从而将消息首先泵入未排序的队列,然后其他处理器可以提取这些消息并将其插入到排序后的队列。无论您采用哪种方式,都将添加另一个层或可靠性/故障。但是,这意味着酸分类处理器是独立的,并且也可以独立扩展。 您也可以使用分类器将邮件泵送到数据存储中,而不是插入队列中。同样,所有这些都取决于可靠性要求以及您要付出多少时间,精力和金钱。