我有一个在群集中运行的Node.js应用程序,因此,有许多应用程序同时运行并接受来自负载均衡器的请求。
考虑我有一个"订阅的概念"在我的应用中,每个订阅都存储在包含dateStart
和dateEnd
字段的中央数据库中。对于每个订阅,我需要发送通知,提醒客户有关订阅到期(例如到期前的第14天,第7天和第3天)。此外,我还需要将订阅标记为已过期,并在时机成熟时执行一些额外的逻辑。
为多实例应用程序处理此类基于时间的事件有哪些最佳做法?
我可以让我的应用程序运行到期例程,例如每隔五分钟,但我将不得不处理并发问题,因为每个实例都会尝试这样做,而且我们不希望提交两次通知。
答案 0 :(得分:2)
几年前,当我们对其中一个系统进行聚类时,我重构了我们系统的预定作业,这与您所描述的问题类似。
我创建了一个群集感知的预定作业监视器,并使用该数据库确保在任何给定时间只有一个正在运行。每个人在启动时都会生成自己唯一的GUID,并将其用作ID。在启动时,他们都会根据指示ID,开始时间和上次运行的表来查看数据库以查看主数据库是否正在运行。如果记录的最后一次运行具有指定时间,则主节点正在运行。如果主服务器正在运行,则其余服务器将继续作为备份运行,并检查给定的时间间隔,以便在主服务器死亡时接管。如果主服务器死亡,那么接管主服务器的服务器将以其ID标记记录并更新时间,然后在其他表中查找与您的订阅类似的作业。主服务器将继续以可配置的间隔查找作业,直到它死亡或重新启动。
在测试期间,我能够启动50多个监视器实例,这些实例都不断尝试成为主要实例。只有一个人会接管并且在测试期间我会手动杀死主要人员并观察其他人都争夺主要人员,但只有一个人会占上风。这种方法依赖于DB记录,只允许其中一个线程根据记录中的先前信息使用合格的更新来更新记录。