dimanche 7 septembre 2014

Architecture micro-services

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure. (Conway's law)
Très tôt dans le développement logiciel une conception de l'architecture s'est imposée naturellement, comme allant de soi. L'Architecture Monolotique qui se caractérise par un découpage technique en trois parties - IHM, Métier et BD - obéit à une organisation des équipes en Technical Unit (DBA, Dev et IHM bossent séparément). Son implémentation est très simple et facilitée par la prolifération de différents frameworks. Mais elle montre très tôt ses limites dans un contexte de cloud computing de scalabilité récurrente. Elle se heurte également à la culture Devops, toute modification - même partielle - entraine un déploiement global de l'application.

L'Architecture micro-services promeut un découpage fonctionnel. L'application est composée de services “autonomes” pouvant être déployés et scalés indépendamment les uns des autres. Ce style d'Architecture implique une organisation des équipes autour de Business Unit (Dev, Admin et IHM travaillent ensemble). Elle permet aussi la cohabitation dans l'application de plateformes technologiques différentes avec des sources de données hétérogènes (RDBMs, NoSQL, XML, JSON, ...).
micro-service-architecture
In a microservice architecture a large number of very small services are deployed and linked up to build systems, with the services mapping closely to business concepts and value.
En complément de l'absence de définition formelle, Heroku, s'inspirant de retour d'expériences acquises sur plusieurs projets, publie sous forme de manifeste The Twelve Factors. Le document décrit en 12 points les caractéristiques et bonnes pratiques (déjà connues des développeurs web) d'une architecture microservice. 

I. Codebase : Le code doit être versionné dans un Repository, de prérence un par service. 
II. Dependencies : Les dépendances doivent être déclarées explicitement et isolées.  
III. Config : Tout changement qui dépend d'un environnement (DB, password, niveau de log, …) doit être géré en dehors du code.
IV. Backing Services : Les services tels que DB, SMTP, Rabbit MQ, … doivent être traités comme des ressources externes accessiibles via des URL, qu'ils soient sur la même machine ou ailleurs sur le réseau.  
V. Build, release, run : L'application doit passer par les phases de build et de release avant son utilisation.
VI. Processes : L'application doit être executée comme un ou plusieurs processus sans état.  
VII. Port binding : Les services douvent être exposés à travers des ports.
VIII. Concurrency : Si l'application doit déléguer du traitement (requête http, tache de fond, ...) il ne faut pas que ce soit à un processus fils ou à un daemon mais à un processus de premier niveau.  
IX. Disposability : Les processus de l'appli doivent pouvoir être démarrés/arrêtés rapidement. Pour faciliter la scalabilité, rendre les déploiements fluides et assurer une reprise après pannes.  
X. Dev/prod parity : Les différents environnements (Dev, Test, Prod, …) doivent être simmilaires, même version d'OS, de BD, ... Ce qu'on est capable de faire en prod, on doit être capable de le reproduire en dev.
XI. Logs : Les logs sont gérés comme des streams. L'affichage sur console ou l'écriture sur disque doit être géré en dehors de l'application. 
XII. Admin processes : Les tâches administratives (migration de BD, execution de script shell, ...) doivent être executées dans des processus (à travers un script par exemple) et non manuellement.

Il y a de multiples raisons objectives de trouver dans les architectures micro-services un futur possible du Système d'Information. En revanche elles exigent des effort supplémentaires pour leur mise en oeuvre, dans la prise en main de nouveaux outils (provisionning, monitoring, déploiement continu), et l'adoption de la culture Devops. Martin Fowler explique dans son article les cas d'utilisation.