Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Patterns pour haute dispo et scalabilité d’une appli web – Partie V

Poster un commentaire

Gérer les pannes matérielles

Le chapitre précédent nous a appris quelques stratégies adaptées au cas de pannes transitoires, c’est à dire qui vont se résoudre d’elles-même.

Mais il peut arriver que le problème soit plus sérieux ou en tout cas prenne beaucoup de temps à se résoudre, des heures plutôt que des minutes. Les stratégies de réitération, même avec un disjoncteur, n’est peut être pas la solution la plus adaptée.

 

Peut t’on protéger mieux l’application contre ce problème?

Je vais aborder deux solutions possibles:

  1. la redondance matérielle
  2. Le découplage des modules
  3. Usages d’une queue

Redondance

Revenons sur ce schéma:

2016-08-14_00-21-16

Il nous a permit d’expliquer pourquoi la défaillance d’un seul composant met en péril l’ensemble de l’application.

Je m’intéresse à la partie droite qui suggère une solution simple: redonder les éléments matériels de l’application:

  • Plusieurs sites
  • plusieurs instances des services
  • plusieurs bases de données

C’est la solution probablement la plus courante parce qu’elle est intuitive, bien outillée et généralement assez facile à mettre en place sans grosse adaptation du code.

 

Sous Azure, par exemple, nous avons à notre disposition une palette d’outils:

 

Note: il ne suffit pas de déployer une application sur plusieurs serveurs et installer un service d’équilibrage de charge (NLB) pour qu’elle devienne haute dispo.

D’abord il faut que TOUS les modules qui la compose soient redondants, en particulier la base de données.

Il faut aussi que l’application fonctionne dans un tel mode. Les points d’attention seront en particulier les objets de sessions, les répertoires de contenu qui devront peut être devenir des répertoires partagés (impact sur le code?), accès multi-instance à certains services pas forcément prévu pour…

Ne présupposez rien, testez.

 

Une des solutions la plus sophistiquée offerte par Azure est le déploiement à travers plusieurs data center. On a alors besoin de mettre en place un gestionnaire de trafic pour surveiller la capacité du data center à répondre à chaque instant. Azure intègre tout cela dans un service appelé Azure Traffic Manager.

Dans ce schéma votre application est déployées dans au moins deux data center et vous pouvez à tout moment basculer de l’un vers l’autre ou re-router une partie du trafic de l’un vers l’autre.

Le découplage

La redondance sera je pense votre premier choix, mais on a vu quelques limites auxquelles il faut ajouter un coût qui peut être assez élevé et une infra un peu plus complexe. Ce point est surtout un problème en on premises je pense. Sous Azure c’est facile et souvent automatique.
Dans ce cas on peut envisager une autre alternative: découpler les modules.
Dans ce modèle l’application ne dialogue plus directement avec ses parties, mais le fait à l’aide d’un intermédiaire.
Le rôle de cet intermédiaire est de fournir la redondance à un service qui ne peut pas l’être nativement.
Le modèle le plus utilisé est l’utilisation d’une queue. Une queue est un service de communication asynchrone et one-way (les messages circulent dans un seul sens).
La queue est capable d’enregistrer tous les messages destiné au service pendant qu’il se trouve hors ligne.
2016-08-17_23-10-53
Celui-ci n’a plus qu’à les dépiler au moment où il est à nouveau prêt à les traiter.
2016-08-17_23-12-54
Les messages peuvent aisément rester des heures, si ce n’est des mois, dans une queue. C’est donc un moyen efficace de résoudre le problème.
La terminologie employée est la suivante:
producteur -> celui qui injecte un message dans la queue
consommateur -> celui qui traite les messages extraits d’une queue
Il arrive que le consommateur retourne une réponse. On peut procéder de la même façon avec une queue supplémentaire. Les rôles producteur et consommateur s’inversent alors.
La queue peut également jouer d’autres rôles.
Ecrire un message dans une queue est une opération très rapide. Celle-ci peut donc servir de tampon pour absorber l’arrivée massive de traitement que le consommateur ne parvient pas à gérer en temps réel.
A ce titre la queue peut prendre sa place de façon naturelle dans une architecture CQRS dans la pile de traitement des commandes afin d’optimiser les performances en écriture. Une des caractéristiques fréquentes des commandes est en effet qu’elles n’ont habituellement pas besoin d’être effectué dans l’immédiat.
Azure propose deux Queues
  1. Storage Queue
    Messages jusqu’à 64 Ko, mais le message peut être un simple lien vers un blob
    TTL <= 7 jours
    Pas de garantie FIFO
    Pas de transaction
    Rapide, latence < 10 ms
  2. Service Bus Queue
    Gestion de topics (émission multicast de messages)
    Jusqu’à 256 Ko
    Transaction locale
    On peut organiser du FIFO
    TTL illimité

 

L’accessibilité FIFO est un point d’attention. Vos donnés sont ou pas sensibles à l’ordre de traitement.

Ce point ne va pas de soi. En effet, un service de traitement des messages est un composant qui peut parfaitement faire l’objet d’un autoscalling. Il est donc possible d’avoir plusieurs instances à un moment donné. La possibilité de mettre les consommateurs en concurrence peut être mise en œuvre avec un pattern « Competing Consumer » qui ne sera pas abordé ici:

https://msdn.microsoft.com/en-us/library/dn568101.aspx

Autres usages

  • Tampons pour absorber un flux important
  • Tampon pour absorber un flux vers un service structurellement  mono thread (écriture dans un fichier)
  • On rencontre parfois une queue dans les architectures CQRS pour optimiser la pile des commandes.
    Mais pas seulement. Queue est aussi un bon outil pour les situations où CQRS n’est pas intéressant, c’est à dire où commandes et requêtes ne sont pas ou peu en concurrence.

Démonstration

La démo s’appelle sans surprises EscarGoQueue. J’ai décidé d’implémenter un Azure Storage Queue. C’est un bon choix dans mon contexte.
L’implémentation du repository (QueueRepositoryAsync) est très similaire à celle présentée pour les TABLE et ne présente aucune difficultés.
Je vais utiliser les queues pour gérer l’enregistrement des achats de billets de chaque course. c’est en effet un service critique (il me rapporte de l’argent!!!!) et je dois donc le blinder. J’ai donc réécrit le repository des tickets pour s’appuyer sur celui des queues. En l’occurrence il s’agit de TicketModelBuilderQueue.
C’est le service chargé de fournir le vue/modèle des tickets au contrôleur.
Le code n’est pas suffisamment complexe pour mériter de le détailler. Vous avez accès au code dans mon espace GitHub comme toujours.
Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s