0

J'ai une application Node.js qui s'exécute dans un cluster. Par conséquent, de nombreuses instances d'une application s'exécutent simultanément et acceptent les demandes de l'équilibreur de charge. Considérons que j'ai une notion d'un "abonnement" dans mon application, et chaque abonnement est stocké dans la base de données centrale avec dateStart et dateEnd champs. Pour chaque abonnement, j'ai besoin d'envoyer des notifications, rappelant aux clients l'expiration de l'abonnement (par exemple, 14, 7 et 3 jours avant l'expiration). Aussi, je devrai marquer un abonnement comme expiré et effectuer une logique supplémentaire, quand le temps viendra. Quelles sont les meilleures pratiques pour gérer ces événements basés sur le temps pour les applications multi-instances?Comment gérez-vous les événements basés sur le temps dans un cluster?

Je peux faire en sorte que mon application exécute une routine d'expiration, par ex. Toutes les cinq minutes, mais je vais devoir traiter des problèmes de concurrence, car chaque instance essaiera de le faire et nous ne voulons pas que les notifications soient soumises deux fois.

Répondre

1

J'ai refaçonné les tâches planifiées pour l'un de nos systèmes lorsque nous l'avons regroupé il y a quelques années, un problème similaire à celui que vous décrivez.

J'ai créé un moniteur de travail planifié compatible cluster et utilisé le DB pour m'assurer qu'un seul fonctionnait à un moment donné. Chacun a généré son propre GUID unique au démarrage et l'a utilisé pour un ID. Au démarrage, ils se tournent tous vers la base de données pour voir si un serveur principal fonctionne en fonction d'une table indiquant l'ID, l'heure de début et la dernière exécution. Un primaire est en cours d'exécution si la dernière exécution enregistrée a une durée spécifiée. Si un primaire est en cours d'exécution, le reste reste en cours d'exécution en tant que sauvegardes et vérifie sur un intervalle donné pour prendre en charge si le primaire devait mourir. Si le primaire meurt, celui qui prend le relais en tant que primaire marque l'enregistrement avec son identifiant et met à jour les temps, puis recherche les jobs dans d'autres tables qui seraient similaires à vos abonnements. Le serveur principal continuera à rechercher des travaux à un intervalle configurable jusqu'à ce qu'il meure ou soit redémarré. Pendant les tests, j'ai été capable de faire tourner plus de 50 instances du moniteur qui essayaient constamment de devenir primaires. Une seule personne prendrait la relève et pendant les tests, je tuerais manuellement le primaire et regarderais les autres, mais un seul l'emporterait. Cette approche repose sur l'enregistrement de la base de données pour autoriser uniquement l'un des threads à mettre à jour l'enregistrement à l'aide de mises à jour qualifiées basées sur les informations préalables de l'enregistrement.

+0

Merci de prendre votre temps pour partager ceci. Cela ressemble à une solution robuste, je vais garder cela à l'esprit! Cependant, je pensais à une approche similaire avec le verrouillage de niveau ligne, mais à un niveau plus granulaire. Je pensais que chaque travailleur pouvait extraire les "travaux" en attente de la base de données et verrouiller les lignes pour le traitement, puis marquer chaque travail comme "complet". J'espère que le travail sera réparti plus uniformément entre toutes les instances et que le verrouillage empêchera les travailleurs de saisir des tâches déjà en attente. Qu'est-ce que tu penses? –

+0

Cette approche est également valable si vous souhaitez profiter des multiples nœuds pour gérer la charge de travail. J'ai choisi de faire du rôle principal le point de discorde de telle sorte que tout ce dont j'avais besoin pour m'occuper de moi était de faire en sorte qu'un seul devienne primaire et travaille les emplois. Je pense que tant que sur chaque fiche de travail vous avez un statut en vol, marquez qui travaille et quand ils ont touché le travail pour la dernière fois, vous devriez être capable de déterminer si un travail a échoué et le reprendre après un délai raisonnable. – NinePlanFailed