Comme indiqué dans le billet "Vers une infrastructure en micro services", Gadz.org s'oriente vers une architecture en micro service. J'expose ici les problèmes que cela pose pour la gestion des erreurs.

Classification des erreurs

Lors du traitement d'un message, un service consommateur peut rencontrer des erreurs. Il s'agit d’événement empêchant le traitement correct du message.

On sépare trois 3 natures d'erreurs :

Les erreurs "métier"

 Il s'agit d'erreurs liées à la logique métier du service. Exemples : inscription d'un utilisateur à une liste de diffusion dont il fait déjà partit, attribution d'une adresse mail déjà attribuée...

Les erreurs "techniques"

Ce sont des erreurs qui apparaissent lors de l'execution du service. Exemples : Reception d'un message ne respectant pas le format défini les spécifications, bug du à un caractère invalid ou tout autre bug provoquant l’interruption involontaire du service.

Les erreurs de disponibilité

Elles interviennent lorsqu'une ressource extérieure nécessaire au traitement du message n'est pas disponible. Exemple : base de donnée indisponible, accès aux API Google suite à un dépassement de quota, etc. Ces erreurs sont parfois considérées comme un cas particulier des erreurs techniques.

 

Il est également possible de classer les erreurs en 2 types :

Les erreurs remédiables

Une erreur est dite remédiable lorsque le meme message peut être traiter en reessayant plus tard ou en étant traiter d'une autre manière (eventuellement en l'envoyant à un autre service)

Les erreurs irdiables

Les erreurs irrémédiables sont dues à la nature même du  message ou à l'implémentation technique du service. Ce message ne pourra jamais être traiter

Les erreurs de disponibilité sont généralement remédiable. A l'inverse, les erreurs technique sont souvent irrémédiables.

La gestion des erreurs

Première approche

Dans une première approche, nous avons choisi une solution simple de la gestion des erreurs. Nous ne considérons que 2 types d'erreurs : les erreurs remédiables (Softfail) et les erreurs irrémédiables (Hardfail). Il s'agit d'une généralisation de l'approche utilisée par les X lors du développement de GappsD [Github] notre ancien système de synchronisation GoogleApps. Les règles sont les suivantes :

  • Lors d'un Hardfail, le message est abandonné et simplement transmis au système de log centralisé pour en garder une trace
  • Lors d'un Softfail, le message est stocké dans une zone tampon pour être réinjecté automatiquement dans le système après une certaine période (30 minutes par défaut). Un Hardfail est déclenché au bout de 10 tentatives.

La zone tampon est indépendante du service qui a provoqué l'erreur. En pratique, nous utilisons une queue RabbitMQ ayant une date d'expiration [documentation technique]

Voici un exemple d'utilisation : 



Cet exemple illustre le fonctionnement de l'appel à un service GoogleApps Service chargé de créer des compte Google en utilsant les API de Google. Le service est appelé explicitement via l'utilisation de la clé de routage "request.googleapps.user.create"

Etapes :

  1. Gram Producer envoie un message avec la clé de routage "request.googleapps.user.create" à l'exchange Agoram Exchange
  2. Le message est transmis aux queue abonnée à la clé de routage "request.googleapps.user.create". Ici seulement la queue GoogleAppsService Queue
  3. Le message est stocké dans la queue GoogleAppsService Queue en attendant que GoogleAppsService le récupère
  4. GoogleAppsService récupère le message et le traite. Les API Google n'étant pas disponibles, une erreur Softfail est levée.
  5. Cette erreur est ajoutée au contenu du message
  6. Le message est envoyé dans la queue GoogleAppsService Deferred Queue via GoogleAppsService Producer
  7. Après 30 minutes, le message est renvoyé dans l'exchange Agoram Exchange avec la clé de routage d'origine : "request.googleapps.user.create"
  8. Les étapes 2 à 7 sont répétées jusqu'à ce que l'API Google soit de nouveau disponible ou que 10 erreurs Softfails soient inscrites dans le message
  9. Si 10 erreurs Softfail soient inscrites dans le message, le message est envoyé dans l'exchange avec la clés de routage "agoram.log"

Cette approche à plusieurs avantages :

  • L'ensemble des messages transitant via l'exchange principal étant loguées, toutes les erreurs sont logguées de manière centralisée. La detection des défaillance est donc facilité. Le service peut de sont coté avoir ses propres logs. 
  • La gestion de la zone tampon n'est pas confié au service mais au système de messagerie via une approche standard. Cela permet d'éviter qu'une défaillance du service n’entraîne une perte des messages.
  • Elle est relativement simple à mettre en place et monitorer.

Limitations

Mais cette approche ne fonctionne que dans un cas très précis : le message ne peut exister qu'à un seul endroit à la fois. Il ne peut pas être dupliquer pour être envoyé à plusieurs services simultanément.

Prenons un autre exemple pour mieux comprendre le problème :

Dans cet exemple nous changeons de fonctionnement. Plutôt que d'appeler explicitement les services, nous utilisons un système de "notification". A chaque nouvel utilisateur enregistré dans l'application GrAM, un message avec la clé de routage "notify.gram.user.created" est envoyé. Les services abonnés à cette notification recevront le message. Dans cet exemple, 2 services sont abonnés à "notify.gram.user.created" :

  • GoogleApps Service, chargé de la création des comptes Google
  • WelcomeMail Service, chargé d'envoyer un mail de bienvenu aux nouveaux inscrit avec toutes les informations leur étant necessaire

Reprenons le fonctionnement précédent :

  1. Gram Producer envoie un message avec la clé de routage "notify.gram.user.created" à l'exchange Agoram Exchange
  2. Le message est transmis aux queue abonnée à la clé de routage "notify.gram.user.created". Ici, il s'agit des queues GoogleApps Service Queue et WelcomeMail Service Queue
  3. Le message est dupliqué et stocké dans les queue en attendant que les différents services le récupère
  4. WelcomeMail Service récupère le message et le traite. Un mail est envoyé à l'utilisateur
  5. GoogleAppsService récupère le message et le traite. Les API Google n'étant pas disponibles, une erreur Softfail est levée.
  6. Cette erreur est ajoutée au contenu du message
  7. Le message est envoyé dans la queue GoogleAppsService Deferred Queue via GoogleAppsService Producer
  8. Après 30 minutes, le message est renvoyé dans l'exchange Agoram Exchange avec la clé de routage d'origine : "notify.gram.user.created"
  9. Les étapes 2 à 8 sont répétées jusqu'à ce que l'API Google soit de nouveau disponible ou que 10 erreurs Softfails soient inscrites dans le message
  10. Si 10 erreurs Softfail soient inscrites dans le message, le message est envoyé dans l'exchange avec la clés de routage "agoram.log"

En suivant ce protocole, un nouveau mail est envoyé à chaque Softfail généré par GoogleApps Service. De plus, si des erreurs apparaissent simultanément dans plusieurs services, l'historique des erreurs présent dans le contenu du messages ne sera pas cohérent entre les différentes instances de ce message.

Plus généralement, ceci pose la question du traitement des Softfails. Doit-on ré-effectuer toutes les actions ou uniquement celles en erreur ?

Une autre approche est donc necessaire. Les différentes solutions envisagées feront l'objet d'un autre billet de blog.

N'hésitez pas à participer et proposer des solutions via les commentaires ou sur le Slack de Gadz.org

Depuis plusieurs années, Gadz.org s'oriente vers une architecture découpée en services, voir en micro-services. Voyons ensemble ce que cela signifie et les raisons de ce choix.

Cet article ne rentre volontairement pas dans les détails techniques. Cecis feront l'objets d'autres billets de blog. Pour les plus impatients, n'hésitez pas à poser vos questions en commentaire


L'architecture en services c'est quoi ?

Architecture en services

L'architecture orienté service vise à résoudre un problème récurent dans les environnement informatique : l'augmentation boulimique des fonctionnalités des applications. Les applications grossissant, leur complexité augmente pour finalement devenir d'énormes monstres que plus personne n'ose modifier de peur de "casser" quelque chose. Rajoutez à cela des resources humaines avec un fort turnover vous serait assurer d'avoir perdu toute votre agilité.

Pour répondre à ce problème, les applications sont découpées en applications plus petites ayant chacun un périmètre fonctionnel bien défini.

 Mais ces applications ne sont que rarement autonomes et ont besoin de communiquer avec les autres applications, le plus souvent au moyen d'API [wikipedia]. Dans les systèmes Gadz.org  par exemple, lors de l'inscription d'un nouvel utilisateur dans le site de la Soce, il est également nécessaire de l'inscrire dans le système d’authentification universel.

Architecture en services : plusieurs applications qui dialoguent entre elles

Cette architecture présente un gros avantage  : le découpage des équipes projets. Il nous est ainsi possible de sous-traité le développement du site de la Soce tout en l'intégrant au sein d'un environnement applicatif plus large. Elle nous permet également de trouver des briques "toute faites" dans le commerce ou open-source.

Mais l'architecture en services ne résout pas tout ! La complexité n'a pas été supprimée elle a été déplacée. Le parc applicatif évoluant, les liens entre les applications s'intensifient au point de créer des couplages fort entre le fonctionnement des applications et de brouiller les pistes entre les responsabilité de chacune.

Deuxièmement, les "services" restent des applications à part entière, nécessitant chacune de multiple compétences (gestion de base de données, envoie de mail...) et une bonne connaissance de la base de code pour en assurer l'évolutivité. Même si le phénomène est amoindir, les équipes projets restent de tailles conséquente, ce qui est un problème pour des organisations telles que la notre, reposant sur des bénévoles. De plus, la complexité des applications pose généralement une barrière à l'entrée pour les nouveaux bénévoles, souvent débutants.

Architecture en micro-services

Pourquoi ne pas faire des applications encore plus petites ?

C'est ce que proposent les architecture en micro-services. Pour éviter les problèmes des gros projets, il suffit de n’avoir que des petits projets.
 
Architecture en micro-services : plein de petites applications qui dialoguent entre elles

Ceci présente de nombreux avantages :

  • L'application étant de taille limité, les "cas particuliers" sont peu nombreux et facilement identifiables
  • Les équipes projets sont réduites et plus spécialisées
  • L'architecture force les interfaces à être formalisées, une obligation de documenter les entrées-sortie de son application
  • Les technologie utilisées sont indépendantes et permettent de sélectionner celle qui répond le mieux aux besoins spécifiques
  • Il est plus facile de démarrer un nouveau projet en s'appuyant sur les services existants
  • L'amélioration des performances est simplifiée : il est plus facile d'identifier le service le plus lent et de l'améliorer

Evidemment, les micros-services ne sont pas une solution miracle et il viennent avec leur lot de complications :

  • L'industrialisation (la mise en production) est plus complexe : "beaucoup de petites applications" signifie "beaucoup de déploiements", ce qui peut être pénible à réaliser si le processus de déploiement est lourd à utiliser
  • Les interfaces doivent être documentées : c'est également un inconvénient car un service non documenté deviendra rapidement inutilisable
  • Le système devient distribué : la vision globale est plus compliquée à atteindre et nécessite beaucoup de communication entre les équipes

Chez Gadz.org, ça donne quoi ?

L'architecture Gadz.org

Nous avons opté pour une architecture en "bus de message" plutôt que d’utiliser des API [les architectures microservices]. Vous pourrez en apprendre plus sur les détails techniques sur la page de l'Architecture Orientée Service (SOA). A l'heure de l'écriture de cet article, elle est encore en cours de construction et de formalisation mais les progrès sont rapide.

Et maintenant ?

L'histoire de Gadz.org a montré qu'il est difficile de maintenir de grosse applications dans un contexte où la resource bénévole est incertaine. Bien souvent, lorsque les initiateur d'un projet s'en vont, la connaissance part avec eux. De plus, il est compliqué de "passer la main" car la complexité des applications décourage rapidement les nouveaux venus.

Nous espérons que cette nouvelle architecture réduira cette barrière à l'entrée en permettant aux débutant d'appréhender nos systèmes petits à petit et en leur donnant la possibilité d'ajouter de nouvelle fonctionnalités dès leur arrivée, en utilisant les technologies avec lesquelles ils sont à l'aise.

Si ce sujet vous intéresse, laissez des commentaires sur Confluence et venez nous rejoindre sur Slack !

Sources

http://blog.octo.com/larchitecture-microservices-sans-la-hype-quest-ce-que-cest-a-quoi-ca-sert-est-ce-quil-men-faut/

La sauvegarde et restauration des bases de données est une problématique majeur pour tout DBA. OpenLDAP n’échappe pas à cette règle cependant il n'existe que très peut d'outil pour effectuer des sauvegarde de ces bases.

 

Les outils fournis avec slap pour sauvegarder et restaurer proposent d'exporter la base sous forme d'un fichier plat ldif. Cependant l'exportation et la conversion peut prendre du temps. Pour notre base (environ 200Mo) il faut presque 1h pour réaliser l'export et l'importation qui recalcule les indexes peut prendre jusqu’à 4h.

 

Je vous propose dans ce billet une autre méthode pour faire des export / import de base ldap. Elle se base sur l'utilisation de db-util pour recopier les fichiers bruts avec lesquels travail Openldap. Avec cette methode le temps de sauvegarde restauration peut passer de 1h à 5min.

Sauvegarde

Ce script fonctionne de la façon suivante :

  1. Utilisation de "db5.3_hotbackup" pour faire une sauvegarde cohérente des fichiers ldap
  2. Export en ldif de la configuration uniquement de la base
  3. Réalisation d'un targz contenant le fichier de configuration + les datafile

 

 

Restauration

Ce script fonctionne de la facon suivante :

  1. Couper l'instance LDAP
  2. Suppression des fichiers existants et configuration
  3. On fait un split du fichier de configuration présent dans la sauvegarde
  4. On insert les configurations de schema
  5. On insert les configurations de backend
  6. On insert les configurations de olcDatabase
  7. On insert les droits
  8. On démare une premiere fois le ldap (a vide)
  9. On Modifie les entrées qui ne peuvent etre modifié qu'une fois la base lancé (emplacement du répertoire contenant les données, ...)
  10. On coupe la base
  11. On recopie les datafile présent dans la sauvegarde
  12. On fixe les droits sur les fichiers et repertoires
  13. On lance la base

 

 

 

 

 

 

Prérequis

Procédure

  1. Couper la VM sur le ESX old proprement (commande sudo halt)
  2. Cliquer sur la VM dans l'onglet résumé sur le vsphere du pcc old
  3. Fichier => exporter => export OVF
  4. Enregistrer la VM sur votre machine locale
  5. Déployer une VM via ovftool sur le nouveau ESX à l'aide de la commande suivante :

  1. Démarrer la VM sur le nouveau PCC

Avec ce nouveau départ (voir Un nouveau départ) nous avons l'occasion de remettre a plat une partie de notre infrastructure. Avec les années nous avons accumulé des services sur l'organisation existante. Et nous n'avons pas du tout eu le temps de la repenser pour s'adapter aux nouvelles exigences.

 

L'idée est ici de rationaliser le nombre de serveur et surtout de ne pas obtenir comme par le passé des serveurs qui font "un peut de tout".

Au départ l'infra 

De quoi ont besoin nos services pour fonctionner :

  • Des middleware ( apaches, nginx et reverse proxy)
  • Des bases de données (mysql, postgresql, ldap)
  • Du réseau (DHCP, ntp et proxy)
  • Du stockage (NFS)
  • Du DNS (bind)
  • De l'annuaire de services (consul)
  • De la gestion de conf (puppet / ansible)
  • De l'integration continue (bamboo)

En essayant de rassembler au sein d'un même serveur les services similaires on obtiens la répartition suivante :

TypeServiceNom serveur
middlewarereverse proxyXanthe
middlewareapacheBrontes
middlewarenginxBrontes
Base de donnéemysqlBelenos
Base de donnéepostgresAtlas
Base de donnéeldapHygie
RéseauDHCPToutatis
RéseauNTPToutatis
RéseauproxyToutatis
Stockage NASNFSToutatis
DNSBindDispater
Annuaire de serviceConsulToutatis
Gestion de confPuppetToutatis
Intégration continueBambooBorvo

 

Dans quel ordre

Soit des services a installer dans l'ordre ci-dessous :

  1. Toutatis : NTP, proxy, puppet, consul
  2. Hygie : ldap
  3. Dispater : dns
  4. Atlas : postgres
  5. Belenos : mysql
  6. Xanthe : reverse proxy
  7. Brontes : apache ,  nginx
  8. Borvo : integration continue
Un nouveau départ

Bonjour à tous,

Voici le premier billet du blog infrastructure de gadz.org. C'est en effet le moment idéal pour réécrire nos documentions car nous allons à partir de lundi prochain réinstaller une grande partie des machines pour les migrer sur un nouveau data-center virtuel.


Fin du support GS sous sa forme actuelle:

L'offre OVH Global Solution (GS) disparaît.GS n'est pas remplacée pour l'instant.

Et l'offre MIS qu'il nous proposent n'assure pas l'infogérance sur toutes les services info-géré qu'on a :
  • apache
  • MySQL
  • PGSql
  • LDAP

Suite aux discutions entre les membres de l'équipe roots et la direction de la Soce nous avons décidé de monter une taskforce pour migrer tous nos services sur l'architecture info-géré vers une nouvelle infrastructure en 20 jours.

 

Commande d'un nouveau PCC:

Dorian Becker a passer la commande de la nouvelle infrastructure, elle sera mise à disposition dès que la facture aura été payé par la soce.

Ci-dessous la commande initiale :