0

我有一個在羣集中運行的Node.js應用程序,因此,有很多應用程序同時運行並接受來自負載平衡器的請求的實例。你如何處理集羣中基於時間的事件?

考慮我在我的應用程序中有一個「訂閱」的概念,每個訂閱都存儲在中央數據庫dateStartdateEnd字段中。對於每次訂閱,我需要發送通知,提醒客戶訂閱到期(例如,到期前14天,7天和3天)。此外,我需要將訂閱標記爲過期,並在時間到時執行一些額外的邏輯。

什麼來處理多實例的應用,基於時間的事件的最佳實踐?

我可以讓我的應用程序來運行到期程序,例如每五分鐘一次,但之後我將不得不處理併發問題,因爲每個實例都會嘗試這樣做,而我們不希望通知被提交兩次。

回答

1

我重構計劃作業爲我們的系統之一,當我們在幾年前聚集了,類似的問題,以你所描述的。

我創建了一個集羣感知預定作業監控以及所使用的數據庫,以確保只有一個在任何給定的時間運行。每個在啓動時都會生成自己的唯一GUID,並將其用於ID。在啓動時,他們都會根據指示ID,開始時間和上次運行的表,查看數據庫以查看是否正在運行主服務器。如果記錄的上次運行具有指定的時間,則主要運行。如果主服務器正在運行,其餘的服務器將繼續作爲備份運行,並檢查給定的時間間隔以接管主服務器是否死機。如果主要死亡人員(接管主要死亡人員的人員使用其ID標記記錄並更新時間),則在其他表格中查找與您的訂閱類似的作業。主要人員將繼續以可配置的時間間隔查找作業,直到它死亡或重新啓動。

在測試過程中,我能夠旋轉起來50+,所有試圖不斷成爲主要監視器的實例。只有一個人會接管,在測試過程中,我會手動殺死小學生,並觀察其他人都爭奪小學生,但只有一個人會佔上風。此方法依賴於數據庫記錄,只允許其中一個線程根據記錄中的先前信息使用合格的更新更新記錄。

+0

感謝您抽出時間來分享。它看起來像一個強大的解決方案,我會牢記這一點!但是,我正在考慮採用行級鎖定的類似方法,但在更細化的級別上。我在想,每個工作人員都可以從數據庫中提取掛起的「作業」,並鎖定要處理的行,然後將每個作業標記爲「完成」。我希望通過這種方式,工作將更均勻地分配到所有實例中,鎖定將防止工作人員抓住已經掛起的工作。你怎麼看? –

+0

如果您想利用多個節點來處理作業負載,那麼這也是一種有效的方法。我選擇把主要角色作爲爭論的焦點,這樣我所需要關心的就是確保只有一個人成爲首要工作並且工作。我認爲,只要在每個工作記錄中您都有一個空中狀態,標記誰在工作,以及他們最後一次接觸工作的時間,您應該能夠確定工作是否失敗,並在合理的超時後恢復工作。 – NinePlanFailed