Question

Je sais que, avec Network Load Balancing et Failover Clusteringwe peut faire services passifs haute disponibilité. Mais qu'en est- applications actives

Exemple: Un de mes applications récupère une partie du contenu d'une ressource externe dans un intervalle fixe. Je l'ai imaginé les scénarios suivants:

  1. Exécuter dans une seule machine. Problème: si l'instance tombe, le contenu ne sera pas récupéré
  2. Exécuter dans chaque machine du cluster. Problème: le contenu sera récupéré plusieurs fois
  3. Faites-le dans chaque machine du cluster, mais l'exécuter que dans l'un d'eux. Chaque instance devra vérifier une sorte de ressource commune de décider si elle son tour de faire la tâche ou non.

Quand je pensais à la solution # 3 Je me suis demandé ce que devrait être la ressource commune. J'ai pensé à créer une table dans la base de données, où nous pourrions l'utiliser pour obtenir un verrou global.

Est-ce la meilleure solution? Comment les gens ne le font habituellement cela?

Par la façon dont il est un C # .NET WCF application en cours d'exécution sur Windows Server 2008

Était-ce utile?

La solution

Pour de tels problèmes, ils ont inventé des files d'attente de messages. Imaginez le cas où vos applications en cluster écouter tous à une file d'attente de messages (lui-même cluster :-)). À un certain moment une instance obtient votre commande initiale pour télécharger votre ressource externe. En cas de succès, votre instance vide le message et au lieu qu'il affiche un autre pour un temps d'exécution plus tard pour un montant équivalant à la durée de fonctionnement '+' intervalle. Mais dans le cas où les matrices d'instance au cours du traitement, ce n'est pas un problème. Le message est annulée dans la file d'attente (après le délai) et une autre instance peut le ramasser. Un peu de transactions, un peu de files d'attente de messages

Je suis sur le côté Java EE du monde peut donc vous aider avec les détails de codage

Autres conseils

J'ai une fois mis en œuvre quelque chose de similaire en utilisant votre solution # 3.

Créer une table appelée quelque chose comme resource_lock, avec une colonne (par exemple locking_key) qui contiendra une clé de verrouillage.

Ensuite, à chaque intervalle, toutes les instances de votre application:

  1. Exécuter une requête comme 'update resource_lock set resource_key = 1 where resource_key is null'. (Vous pouvez bien sûr également insérer un identifiant spécifique-serveur, un horodatage, etc.)
  2. Si 0 lignes mises à jour. Ne rien faire - une autre instance d'application est déjà la ressource aller chercher
  3. Si 1 ligne mise à jour: chercher la ressource et ensemble locking_key retour à null.

Il y a deux avantages à ceci:

  • Si l'un de vos serveurs tombe en panne, la ressource sera toujours récupérée par les serveurs qui sont encore en cours d'exécution.
  • Vous quittez le verrouillage à la base de données, cela vous évite de vous-même la mise en œuvre.

Il y a des exigences que vous le savez probablement, mais ne sont pas décrits dans la question qui font de donner une réponse éclairée difficile. Certaines de ces questions sont:

  • La tâche devra mener à bien?
  • Si la tâche ne / ne se termine pas correctement, « qui » a besoin de savoir et quel type d'actions doivent être effectuées?
  • Quel est le comportement si la tâche n'a pas terminé lorsque vient le temps d'exécuter la tâche à nouveau? Faut-il exécuter ou non?
  • Quelle est l'importance d'exécuter des emplois à l'intervalle spécifié? Si l'intervalle est toutes les 5 minutes t-il à toutes les 5 minutes ou pourrait l'exécution de la tâche au bout de 5 minutes et 10 secondes?

La première étape consiste à répondre à la façon dont la tâche périodique sera planifiée. Une option est une tâche planifiée Windows, mais qui ne sont pas par nature hautement disponible, mais il peut être possible de travailler autour de cela. Si vous utilisez SQL Server, une autre alternative serait d'utiliser l'Agent SQL Server en tant que planificateur, car il basculera dans le cadre de SQL Server.

L'étape suivante est de déterminer comment invoquer l'application WCF. L'option la plus simple serait de déclencher un emploi pour appeler le service WCF via une adresse IP NLB. Cela pourrait être considéré comme un non-non si le serveur de base de données (ou un autre serveur dans cette zone) appelle à la zone d'application (bien sûr, il y a toujours des exceptions telles que MSDTC).

Une autre option serait utiliser le modèle de file d'attente. Ce serait le plus fiable dans la plupart des situations. par exemple. Agent SQL Server peut exécuter une procédure stockée pour entrer un enregistrement dans une table de file d'attente. Ensuite, sur chaque serveur d'application d'un service pourrait interroger à la recherche d'un dossier mis en attente à traiter. L'accès à l'enregistrement dans la file d'attente sera publié en feuilleton par la base de données de telle sorte que le premier serveur serait exécuter le travail (et ce travail ne ferait que courir une fois).

En fonction des réponses aux questions d'ouverture dans cette réponse que vous pourriez avoir à ajouter un peu plus la gestion des erreurs. Si la récupération de la ressource externe est généralement assez courte, vous voudrez peut-être simplement garder le dossier de file d'attente verrouillée avec un select for update et lorsque la tâche est terminée mise à jour de l'état (ou supprimer l'enregistrement si vous le souhaitez). Cela va bloquer d'autres instances de service de traitement du dossier alors qu'il est en cours de traitement sur un autre serveur et si un accident se produit pendant le traitement de la transaction doit être annulée et un autre service dans le cluster peut ramasser le dossier. (Bien que, vous pouvez augmenter le délai d'attente de transaction aussi longtemps que vous pensez que vous avez besoin.)

Si la tenue d'un verrou de base de données pendant une longue période n'est pas viable alors vous pourriez changer la logique et ajouter une certaine surveillance des services. Maintenant, quand un travail est commencé le traitement, son statut serait changé de file d'attente à l'exécution et le serveur qui traite le dossier sera mis à jour sur le dossier. Une sorte de tableau d'état de service pourrait être créé et chaque instance de service mettra à jour le l'heure actuelle chaque fois qu'ils scrutin. Cela permettrait à d'autres services dans le cluster à des emplois RETRAITER qui montrent que l'exécution, mais le service qu'ils sont censés être en cours d'exécution sur n'a pas « réinsérée » dans un certain délai.

Cette approche a aussi ses limites: si la tâche effectivement terminée, mais en quelque sorte la connectivité de base de données a été perdu - le travail pourrait courir à nouveau. Bien sûr, je ne pense pas que le problème d'avoir des actions de base de données atomiques associées à d'autres ressources non transactionnelles (par exemple demande Web, système de fichiers) va être facilement résolu. Je suppose que vous écrivez un fichier ou quelque chose -. Si est également placé le contenu externe dans une base de données, une seule transaction garantit que tout est conforme

Du point de vue de la simplicité, le moyen le plus rapide / plus facile à accomplir ce que vous cherchez serait à votre cluster « round-robin » de sorte que pour chaque demande, une machine est sélectionnée (par un service de gestion de cluster ou certains autres) pour traiter une demande. demandes des clients réels ne vont pas directement à la machine qui le gère; ils pointent plutôt à un seul critère, qui agit comme un proxy pour distribuer les requêtes entrantes aux machines basées sur la disponibilité et la charge. Pour citer le lien ci-dessous référencé,

  

équilibrage de charge réseau est un moyen de configurer un pool de machines afin qu'ils prennent tour à tour répondre aux demandes. Il est le plus souvent vu mis en œuvre dans des fermes de serveurs: machines configurés de manière identique qui se propagent à la charge d'un site web, ou peut-être une ferme Terminal Server. Vous pouvez également utiliser pour un pare-feu (ISA) ferme, points d'accès vpn, vraiment, à tout moment vous avez le trafic TCP / IP qui est devenu une charge trop importante pour une seule machine, mais vous voulez toujours qu'il apparaisse comme une seule machine fins d'accès.

En ce qui concerne l'application « actif », cette exigence ne tient pas compte dans cette équation depuis que, l'application « active » ou « passive » fait encore une demande à vos serveurs.

équilibreurs de charge commerciaux existent pour servir les requêtes de type HTTP, de sorte que peut-être dignes d'intérêt, mais avec vous pouvez être mieux servis fonctionnalités d'équilibrage de charge de W2k8, puisant dans celles-ci.

Pour plus d'informations sur la configuration que win2k8, voir cet article .

voir pour une autre détaillée par étape de configuration NLB et la configuration.

A défaut, vous pouvez être bien servi par la recherche / affichage sur ServerFault, puisque votre code d'application n'est pas (et ne doit pas être) strictement conscient que la NLB existe.

EDIT:. Ajouté un autre lien

EDIT (2ème): L'OP a corrigé ma conclusion erronée dans le concept 'actif' vs 'passive de'. Ma réponse à cette question est très semblable à ma première réponse, sauf que le service « actif » (qui, puisque vous utilisez WCF, pourrait facilement être un service Windows) pourrait être divisé en deux parties: la partie de traitement proprement dite, et la partie de la direction. La partie de gestion serait exécuté sur un seul serveur, et agir comme un équilibreur de charge à la ronde pour les autres serveurs qui font le traitement proprement dit. Il est un peu plus compliqué que le scénario original, mais je crois qu'il serait une bonne souplesse, ainsi que d'offrir une séparation nette entre votre logique de traitement et de gestion.

Dans certains cas, les gens trouvent utile d'avoir 3 machines qui font toutes les demandes, puis de comparer les résultats à la fin, pour vous assurer que le résultat est tout à fait correct et aucune défaillance matérielle a causé aucun problème durant le traitement. C'est ce qu'ils font pour les avions d'instance.

À d'autres moments, vous pouvez vivre avec avoir un mauvais résultat et un petit temps d'arrêt pour passer à un nouveau service, mais je veux juste le prochain à être ok. Dans ce numéro de solution de cas 3 avec un moniteur de rythme cardiaque est une excellente configuration.

D'autres fois encore, les gens juste besoin d'être informé par SMS que leur service est en panne et l'application il suffit d'utiliser des données obsolètes jusqu'à ce que vous effectuez manuellement une sorte de basculement.

Dans votre cas, je dirais que ce dernier est probablement plus utile pour vous. Puisque vous ne pouvez pas vraiment dépendre du service à l'autre extrémité étant disponible, vous auriez encore à trouver une solution pour ce qu'il faut faire dans ce cas. Redonner des données obsolètes peut être ce qui est bon pour vous, et il ne peut pas être. Désolé d'avoir à dire: Cela dépend

.

Zookeeper fait un bon cas d'utilisation de verrous distribués. Zookeeper ont z noeuds qui sont comme répertoire des données.

Même conservateur a beaucoup de netflix recettes déjà fait et à utiliser. Comme: élection du chef, verrou distribué et beaucoup d'autres.

Je pense que nous avons client de Zookeeper pour C #. Vous devriez certainement essayer cette option. # Option3

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top