Quels modèles de conception sont les plus utilisés pour créer des applications à haute disponibilité? [fermé]

StackOverflow https://stackoverflow.com/questions/814742

Question

De même, y a-t-il des modèles de conception à éviter?

Était-ce utile?

La solution

Je suppose que vous écrivez une application de type serveur (laissez les applications Web pendant un moment - il existe quelques solutions prêtes à l'emploi qui peuvent vous aider, alors regardons la section "J'ai ce nouveau type de le serveur que j’ai écrit "mais je veux que ce soit un problème de haute disponibilité).

Dans une implémentation de serveur, les demandes des clients sont généralement converties (sous une forme ou une autre) en un type de type d'événement ou de commande, puis exécutées sur une ou plusieurs files d'attente.

Donc, premier problème - il est nécessaire de stocker les événements / commandes de manière à survivre dans le cluster (c.-à-d. lorsqu'un nouveau nœud prend le relais en tant que maître, il regarde la prochaine commande qui doit être exécutée et commence).

Commençons par un seul implémentation de serveur threadé (le plus simple - et les concepts s’appliquent toujours aux multi-threads, mais il a son propre ensemble de problèmes0. Lors du traitement d’une commande, un traitement de transaction est nécessaire.

Une autre préoccupation concerne la gestion des effets secondaires et comment gérez-vous l’échec de la commande en cours? Dans la mesure du possible, gérez les effets secondaires de manière transactionnelle, de manière à ce qu'ils soient tout ou rien. c'est à dire. si la commande change les variables d'état, mais se bloque à mi-chemin de l'exécution, elle peut revenir à la valeur "précédent". l'état est grand. Cela permet au nouveau nœud maître de reprendre la commande bloquée et de simplement réexécuter la commande. Un bon moyen consiste à décomposer un effet secondaire en tâches plus petites pouvant à nouveau être exécutées sur n’importe quel nœud. c'est à dire. stocke les tâches de début et de fin de la requête principale, avec beaucoup de petites tâches qui gèrent un seul effet secondaire par tâche.

Ceci introduit également d’autres problèmes qui affecteront votre conception. Ces variables d'état ne sont pas nécessairement des mises à jour de bases de données. Ils peuvent être des états partagés (par exemple une machine à états finis pour un composant interne) qui doivent également être distribués dans le cluster. Ainsi, le modèle de gestion des modifications tel que le code maître doit afficher une version cohérente de l'état dont il a besoin, puis valider cet état sur le cluster. Utiliser une forme de stockage de données immuable (du moins du thread principal effectuant la mise à jour) est utile. c'est à dire. toutes les mises à jour sont effectivement effectuées sur de nouvelles copies qui doivent passer par une sorte de médiateur ou une façade qui met à jour uniquement les copies locales en mémoire avec les mises à jour après la mise à jour sur le cluster (ou le nombre minimum de membres sur le cluster pour la cohérence des données).

Certains de ces problèmes sont également présents dans les systèmes de production maître.

Nécessite également une bonne gestion des erreurs, car le nombre de problèmes pouvant survenir lors de la mise à jour de l'état augmente (car le réseau est maintenant impliqué).

J'utilise beaucoup le modèle d'état. Au lieu de mises à jour sur une ligne, pour les effets secondaires, vous souhaitez envoyer des demandes / réponses et utiliser des messages spécifiques à la conversation pour suivre la progression.

Un autre problème est la représentation des points finaux. c'est à dire. le client connecté au nœud maître doit être en mesure de se reconnecter au nouveau maître, puis d'écouter les résultats? Ou annulez-vous simplement tous les résultats en attente et laissez-vous les clients soumettre à nouveau? Si vous autorisez le traitement des demandes en attente, vous devez disposer d'un moyen simple d'identifier les points de terminaison (clients) (c.-à-d. Une sorte d'identifiant client dans une recherche).

Vous devez également disposer d'un code de nettoyage, etc.

Beaucoup de files d'attente sont utilisées. Beaucoup de gens vont donc utiliser un bus de messages (jms pour Java) pour transmettre les événements de manière transactionnelle.

Terracotta (toujours pour Java) résout beaucoup de ce problème pour vous - il suffit de mettre à jour la mémoire - la terre cuite est votre façade / médiateur ici. Ils viennent d'injecter les aspects pour votre.

Terracotta (je ne travaille pas pour eux) - introduit le concept de "super statique", afin que vous obteniez ces singletons de cluster larges et sympas, mais vous devez simplement savoir comment cela affectera les processus de test et de développement - c'est à dire. utilisez beaucoup de composition, au lieu d’hériter des implémentations concrètes pour une bonne réutilisation.

Pour les applications Web - un bon serveur d'applications peut aider à la réplication de variables de session et un bon équilibreur de charge fonctionne. En quelque sorte, l’utiliser via un REST (ou la méthode de votre choix de service Web) est un moyen simple d’écrire un service multithread. Mais cela aura des conséquences sur les performances. Cela dépend à nouveau du domaine de votre problème.

Les services de messages (disons jms) sont souvent utilisés pour introduire un couplage lâche entre différents services. Avec un serveur de messagerie décent, vous pouvez faire beaucoup de routage msg (encore une fois, apache camel ou similaire fait un excellent travail). Par exemple, un consommateur collant contre un groupe de producteurs JMS, etc., qui peut également permettre un bon basculement. La file d'attente JMS, etc. peut fournir un moyen simple de distribuer des cmds dans le cluster, indépendamment du maître / esclave. (encore une fois, cela dépend si vous faites du LOB ou écrivez un serveur / produit à partir de zéro).

(si j'ai le temps plus tard, je vais ranger, peut-être mettre plus de détails dans la correction de la grammaire, etc.)

Autres conseils

Une des méthodes permettant de créer un logiciel fiable est le logiciel à blocage uniquement :

  

Un logiciel destiné uniquement aux accidents est un logiciel qui se bloque en toute sécurité et récupère rapidement. La seule façon de l'arrêter est de la planter, et la seule façon de la démarrer est de récupérer. Un système en panne seulement est composé de composants en panne seulement, qui communiquent avec des demandes pouvant être répétées; les erreurs sont gérées en plantant en panne, en redémarrant le composant défectueux et en réessayant toutes les demandes dont le délai a expiré. Le système qui en résulte est souvent plus robuste et fiable, car la récupération après incident est un citoyen de premier plan dans le processus de développement, plutôt que par la suite, et vous n'avez plus besoin du code supplémentaire (et des interfaces et bogues associés) pour un arrêt explicite. Tous les logiciels doivent pouvoir planter en toute sécurité et récupérer rapidement, mais les logiciels ne faisant que des crashs doivent posséder ces qualités, sinon leur absence devient évidente.

Je vous conseillerais de lire le relâcher! par Michael Nygard. Il décrit un certain nombre d'anti-schémas qui ont un impact sur les systèmes de production et de schémas permettant d'empêcher qu'un composant errant de détruire l'ensemble du système. Le livre couvre trois domaines principaux; Stabilité, capacité et conception générale (couvrant la mise en réseau, la sécurité, la disponibilité et l'administration).

Mon ancien lieu de travail a été mordu (à un moment ou à un autre) par à peu près tous les scénarios d'échec décrits par Nygard (avec une perte de revenus pour chaque panne résultante). La mise en œuvre de certaines des techniques et des schémas suggérés par celui-ci a abouti à des systèmes beaucoup plus stables et prévisibles (et oui, le livre est un peu centré sur Java, mais les principes sont applicables dans de nombreux contextes).

Faux:

  

... et il y aura un serveur de stockage

Bon:

  

... et il y aura une ferme de stockage (multiple)   serveurs avec (plusieurs) équilibreurs de charge en face   d'entre eux

  • Placez les équilibreurs de charge devant tout. Pour le moment, vous pouvez avoir 4 moteurs, mais à l'avenir, vous pouvez en avoir 400. Il est donc sage de le gérer uniquement sur le LB, pas toutes les applications utilisant le backend.

  • Utilisez plusieurs niveaux de cache.

  • Recherchez des solutions populaires pour accélérer les choses (par exemple, memcached).

  • Si vous envisagez de renouveler un système, procédez par étapes, en plusieurs étapes. Si vous le faites en une étape importante (éteignez l'ancien, allumez le nouveau et priez pour que cela fonctionne), il échouera probablement.

  • Utilisez les noms DNS pour les choses, par ex. storage-lb.servicename est résolu en adresses de tous les loadbalancers de stockage. Si vous souhaitez en ajouter un, il suffit de modifier le DNS, tous les services commenceront à l’utiliser automatiquement.

  • Restez simple. Plus vous dépendez de systèmes, plus votre service en souffrira.

La conception de systèmes à haute disponibilité (HA) est un domaine de recherche et de développement actif. Si vous examinez ACM ou IEEE, vous trouverez une multitude de documents de recherche sur les qualités de service (disponibilité, fiabilité, évolutivité, etc.) et sur la manière de les atteindre (couplage faible, adaptation, etc.). Si vous recherchez davantage d'applications pratiques, jetez un coup d'œil aux systèmes tolérants aux pannes et aux middlewares conçus pour permettre des fonctionnalités telles que la mise en cluster, la grille ou le cloud.

La réplication et l’équilibrage de la charge (proxy inversé) font partie des schémas les plus courants d’atteinte des systèmes haute disponibilité. Ils peuvent souvent être effectués sans modifier le code du logiciel sous-jacent, à condition qu’il ne soit pas couplé trop étroitement. Même une grande partie des offres en nuage récentes sont essentiellement réalisées grâce à la réplication et à l'équilibrage de la charge, bien qu'elles aient tendance à créer une certaine élasticité pour gérer une large gamme de demandes système.

Rendre les composants logiciels sans état facilite la réplication, car l’état lui-même n’a pas besoin d’être répliqué avec les composants logiciels. L'apatridie est l'une des principales raisons pour lesquelles HTTP évolue si bien, mais les applications doivent souvent ajouter leur propre état (par exemple, des sessions), qui doit ensuite être répliqué.

Par conséquent, il est plus facile de rendre les systèmes à couplage lâche hautement disponibles que les systèmes à couplage étroit. Étant donné que la fiabilité des composants du système détermine la fiabilité globale du système, il peut être nécessaire de remplacer des composants non fiables (pannes matérielles, bogues logiciels, etc.). En permettant une adaptation dynamique au moment de l'exécution, ces composants défaillants peuvent être remplacés sans affecter la disponibilité du système global. Le couplage lâche est une autre raison de l’utilisation de systèmes de messagerie fiables dans lesquels l’expéditeur et le destinataire ne doivent pas nécessairement être disponibles en même temps, mais le système lui-même est toujours disponible.

Si je comprends bien, vous recherchez des modèles spécifiques à utiliser dans les applications java faisant partie d’une architecture haute disponibilité. Bien sûr, il existe un grand nombre de modèles et de meilleures pratiques qui peuvent être utilisés, mais ils ne sont pas vraiment des "modèles HA". Ce sont plutôt de bonnes idées qui peuvent être utilisées dans de nombreux contextes.

Je suppose que ce que j'essaie de dire est le suivant: une architecture à haute disponibilité est composée de nombreuses petites pièces. Si nous sélectionnons une de ces petites pièces et les examinons, nous découvrirons probablement qu’il n’ya pas d’attributs HA magiques pour ce petit composant. Si nous examinons tous les autres composants, nous trouverons la même chose. C’est quand ils sont combinés de manière intelligente pour devenir une application haute disponibilité.

Une application haute disponibilité est une application dans laquelle vous prévoyez le pire dès le début. Si vous pensez en termes de " Ce composant est tellement stable que nous n’avons pas besoin de redondance supplémentaire " ce n'est probablement pas une architecture HA. Après tout, il est facile de gérer les scénarios de problèmes que vous prévoyez. C’est celui qui vous surprend qui fait tomber le système.

Malgré tout, certains modèles sont particulièrement utiles dans les contextes de haute disponibilité. Nombre d'entre elles sont documentées dans le livre classique "Patterns of Enterprise Application Architecture" de Martin Fowler.

Je suis en train d'interpréter " Haute disponibilité ". en tant que " Zero Down Time ", qui peut être implémenté selon une autre question SE:

Déploiement sans interruption pour les applications Java

  1. commutateur A / B: (mécanisme de mise à niveau progressive + mécanisme de secours)
  2. Déploiement parallèle & # 8211; Apache Tomcat: (pour les applications Web uniquement)
  3. Liaison de port retardée
  4. Liaison de port avancée

J'utiliserai certains de ces concepts pour élaborer des modèles de conception du système de haute disponibilité du point de vue logiciel, ce qui complète les approches ci-dessus.

Modèles à utiliser:

Proxy / Usine :

Avoir un objet proxy et le proxy décidera où rediriger les demandes. Supposons que vous ayez la version 1 & amp; Version 2 du logiciel. Si les clients se connectent avec un ancien protocole, redirigez-les vers le logiciel de la version 1. Les nouveaux clients peuvent se connecter directement à la version 2. Le proxy peut utiliser soit la méthode Factory, soit AbstractFactory pour afficher la nouvelle version du logiciel.

Stratégie

Vous pouvez changer d'algorithme au moment de l'exécution en sélectionnant un algorithme parmi une famille d'algorithmes. Si vous prenez l'exemple des compagnies aériennes, vous pouvez basculer entre les algorithmes DiscountFare et NormalFare au cours des mois avec des mois de pointe et de pointe.

Décorateur :

Vous pouvez modifier le comportement de l'objet au moment de l'exécution. Ajouter une nouvelle classe et décorer des responsabilités supplémentaires.

Adaptateur :

Utile lorsque vous changez d'interface ou de contrat entre la version 1 et la version 2. L'adaptateur répondra à la fois à l'ancien & amp; les nouvelles demandes des clients.

Directives générales:

  1. Couplage lâche entre objets
  2. Suivez les S.O.L.I.D dans votre application

Consultez les articles sur le site Web pour connaître les modèles ci-dessus afin de mieux les comprendre.

Ce qu'il ne faut pas utiliser:

Hormis les modèles de conception, vous devez prendre certaines précautions pour obtenir un temps d'indisponibilité zéro pour votre application.

  1. N'introduisez pas un seul point de défaillance dans votre système.
  2. Utilisez des caches distribués (par exemple, Terracotta) / verrouille avec parcimonie.
  3. Supprimez le couplage dur entre services. Supprimez le couplage étroit entre les services en utilisant un bus / framework de messagerie (JMS, ActiveMQ, etc.)

La haute disponibilité concerne davantage la disponibilité et la redondance du matériel que les conventions de codage. Il existe quelques modèles que je voudrais utiliser dans presque tous les cas de HA: je choisirais le modèle de singleton pour mon objet de base de données et utiliserais le modèle d'usine pour créer le singleton. L'usine peut alors disposer de la logique pour gérer les problèmes de disponibilité avec la base de données (c'est là que se produisent la plupart des problèmes de disponibilité). Par exemple, si le maître est en panne, connectez-vous à un deuxième maître pour les lectures et les écritures jusqu'à ce que le maître soit de retour. Je ne sais pas si ce sont les modèles les plus utilisés, mais ils sont les plus utilisés dans mon code.

Bien sûr, cette logique peut être gérée dans une méthode __construct, mais un modèle d’usine vous permettra de mieux contrôler votre code et la logique de prise de décision permettant de traiter les problèmes de connectivité de base de données. Une usine vous permettra également de mieux gérer le motif singleton.

Je voudrais absolument éviter le motif décorateur et le motif observateur . Ils créent tous deux une complexité dans votre code qui rend difficile sa maintenance. Ce sont des cas où ce sont le meilleur choix pour vos besoins, mais la plupart du temps ils ne le sont pas.

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