您如何确保在分布式系统中至少有一次通知?

时间:2018-07-06 16:27:23

标签: design-patterns architecture

让我说我有一个日历活动:

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排序,而不是插入时间,并且我们需要允许删除。

1 个答案:

答案 0 :(得分:1)

  

如何确保分布式通知至少一次   系统吗?

有很多方法可以实现这一点,但是考虑到您的情况,队列是简单的选择。您的要求是通知可靠性,可以将案例中的消息(通知)发送到多个队列,也可以尝试使用主队列,如果失败,则发送到辅助队列。在读取端,如果从辅助读取失败,则可以尝试使用主队列。另外,您还必须确保队列在不同的硬件/机器等上。通过这种方式,您可以避免硬件故障。取决于您的基础平台,Azure,AWS或Google之类的云平台可以帮助您实现可靠队列的长途之路。

  

我们需要   按notification_time排序,而不是插入时间,我们需要允许   删除。

在这里,因为您具有“创建通知”的“多个节点”,所以可以使用简单的管道和过滤器体系结构,从而将消息首先泵入未排序的队列,然后其他处理器可以提取这些消息并将其插入到排序后的队列。无论您采用哪种方式,都将添加另一个层或可靠性/故障。但是,这意味着酸分类处理器是独立的,并且也可以独立扩展。 您也可以使用分类器将邮件泵送到数据存储中,而不是插入队列中。同样,所有这些都取决于可靠性要求以及您要付出多少时间,精力和金钱。