The Lexpage is yours    —  JAYbeezt

Discussions

Refonte vers du microservice

yaug 1471 Spammeur
Chers geeks lexpagiens, bien le bonjour.

Dans mon nouveau taff, on a une belle stack technique à la ramasse, avec du PHP 5, du FLEX (oui oui :D), et autres joyeusetés du genre.
Mais ça tombe bien, j'ai été engagé notamment pour la refonte et pour apporter un peu de nouveauté à cette architecture dépassée.
Le front va être réécrit avec une framework javascript moderne type react ou angular même si à première vue on part sur du vue js.
Du coup, cela va impliquer aussi une refonte de tout le backend (et enfin passer à des trucs modernes qui tiennent plus la route). Mais évidemment cela va devoir se faire par étapes. Je pousse donc pour le moment vers une architecture en micro service.

Cela nous permettrait de faire la refonte du back par étape. En faisant en tout premier une couche d'API gateway on pourrait dans un premier temps renvoyer sur le back actuel, puis au fur et à mesure, réécrire le back en séparant les couches métiers et en les cloisonnant dans des apis. La gateway ne changerait pas mais elle appellerait ensuite les microservices plutôt que le monolithe actuel.
Bref, un schéma classique de refonte d'un projet monolithique vers du microservice.

Vous avez une expérience de genre d'aventure ? Des conseils à donner ?

Je me pose notamment des questions sur la sécurisation de tout cela et la propagation de l'authentification.
Merci :)
Guybrush 8429 Bob
yaugVous avez une expérience de genre d'aventure ?
Aucune, désolé :-/

Mon dévéloppement web n'a pas été plus loin depuis un moment que Django coté backend :-D (et django-rest-framework pour l'API). J'essaie tant bien que mal de rester "au courant de ce qui existe" (j'ai notamment beaucoup apprécié vue.js !) mais je suis clairement dépassé maintenant, que ça soit par l'architecture moderne d'un site web, ou les technologies modernes qui doivent le faire tourner ;-)
Fabe 610 Geek
Félicitations pour ton nouveau job :-)
yaugVous avez une expérience de genre d'aventure ? Des conseils à donner ?
C'est mon gagne-pain depuis quelques années :-p

Je valide ta stratégie d'interposer une Gateway avant de détricoter le monolithe, mais ce n'est possible que si celui-ci est déjà "API-centric", sinon ça demande plus de travail. Le fait d'avoir une application Flex n'est pas un mal car elle a peut être déjà permis de déporter la partie "stateful" dans l'application front et d'avoir un back stateless.
Je pense à la gestion des sessions par exemple.

Tant que tu n'as pas de questions spécifiques on ne peut te donner que des conseils généraux. Celui qui me vient est celui-ci : fais en sorte de garder en tête le "Pourquoi?" on fait du microservice.

Les avantages les plus évidents sont :
* le scaling, on considère qu'il est plus simple de démarrer 100 fois un "petit" composant que deux ou trois fois le "gros" monolithe
* la liberté technologique, "the right tool for the right job" c'est plus simple quand le problème à résoudre est plus petit
* la liberté organisationnelle, chaque équipe peut déployer ses composants de manière autonome sans engager le reste du SI

Si ces avantages ne s'appliquent pas à ta situation, peut être que ton problème ne devrait pas être résolu avec des microservices.
Garder en tête qu'un monolithe avec une architecture solide peut être mieux découplé et plus maintenable qu'un plat de spaghetti de microservices qui s'appellent tous en synchrone. C'est important de se challenger sur ce qu'on fait.

Pour le reste, les bonnes pratiques d'architecture en général s'applique. C'est du archi connu mais je dirais que 12factor.net reste d'une pertinence sans faille et dans une certaine mesure the reactive manifesto. Surtout le principe du "message driven".
yaugJe me pose notamment des questions sur la sécurisation de tout cela et la propagation de l'authentification.Merci :)
Ça sera le boulot de ta gateway de supporter les protocoles de sécurisation, à la Oauth2, JWT, etc...
Elle pourra/devra transmettre l'id du user dans ses requêtes sortantes, le header X-Remote-User est tout indiqué pour cela.

Ensuite, si un microservice A appelle B et que B a aussi besoin d'authentifier l'utilisateur (sont-ce bien deux services distinct déjà?), il faudra que A passe l'authentification dans sa requête. Chez OVH, on avait industrialisé une couche de SDK qui se chargeait d'abstraire le transport (HTTP) et de remplir les headers de requêtes à partir du contexte (la notion de context native à go).

Tu peux aussi vouloir t'assurer que A a le droit d'appeler B. C'est important dans le cas ou A souffre d'une faille de sécu et se retrouve a exécuter du code malveillant, il ne faut pas qu'il puisse appeler des services inhabituels pour lui. Par exemple : le micro service de gestion de compte utilisateurs ne devrait sans doute pas pouvoir appeler le service de gestion des promotions.
Kubernetes ayant remporté la guerre de l'hébergement de conteneurs, le marché se dirige très rapidement vers Istio pour implémenter ce genre d'ACL, ainsi que les features d'intégrations habituelles (logger les requêtes, etc...). Je te recommande pas mal la littérature sur Kubernetes et Istio car même si tu finis par ne pas les utiliser (choix justifiable mais ambitieux), leurs concepts vont revenir tout le temps pendant ta mission.

Mais n'oublie pas : message-driven :-)


Ce message a été modifié 1 fois. Dernière modification : 2 avril 2019 à 10:13 par Fabe.

yaug 1471 Spammeur
Merci Fabe pour ce retour bien construit.
Cela va me donner du grain à moudre et de la lecture.

L'idée du choix du microservice c'était notamment pour découpler les couches métiers et pouvoir faire des pools de microservices en fonction des applis et des domaines.
Le choix n'est pas arrêté pour le moment, et ton retour va me faire y réfléchir pas mal.
trinity 230 Wookie
Je te fais un retour aussi d'ici quelques jours dès que j'ai un peu de temps :-)
Fabe 610 Geek
yaugL'idée du choix du microservice c'était notamment pour découpler les couches métiers et pouvoir faire des pools de microservices en fonction des applis et des domaines.
Ce n'est pas une mauvaise raison mais ce serait mieux que tu puisses l'assoir sur une autre condition. Par exemple, est-ce que les équipes de développement sont séparées par domaines elles aussi ?

Note que le mot "micro-service" est fourre-tout, on peut très bien y ranger des "moyens-services" (en gros, un service par domaine métier).
Une autre manière de faire serait d'implémenter le découplage / la modularité uniquement dans le code, et reconstruire le monolithe tout à la fin.
Si tu restes en PHP, ça te donnerait un repo "monolithe" presque vide et un composer require par module. Ça rend plus compliqué les dépendances directes entre les modules et ça rend la communication par message plus évidente.

Si tu ne pars techniquement de "rien" sur le sujet, il faut aussi penser au côté automatisation : provisioning de l'hébergement, intégration et déploiement continu, gestion de la configuration... Les métiers du DevOps prospèrent sur cette complexité.
Partant de rien, le plus simple est probablement d'opter pour une stack full Cloud. Par exemple Github Pro + Google Cloud Build + Google Kubernetes Engine. Clever Cloud est aussi une option intéressante comme alternative FR. Bien sûr OVH est un choix raisonnable mais la partie CI n'est pas intégrée, il faut aller la chercher ailleurs.
Par contre ça représente quand même un peu de boulot qu'il ne faut pas négliger.


Ce message a été modifié 1 fois. Dernière modification : 2 avril 2019 à 10:43 par Fabe.

Fabe 610 Geek
Je suis bavard mais tu m'as lancé un bel os à ronger, du coup mes idées remontent une par une :-D

Du point de vue sécurité, ça reposera toujours sur une bonne modélisation des menaces. Dans la tienne, peut être que tu voudras t'assurer que les requêtes avec un X-Remote-User proviennent bien de la Gateway (par exemple si tes services sont accessibles d'un autre réseau qui peut avoir été pwned). Ça mettrait en jeu des principes de signatures et du coup peut être remettre du JWT à cet endroit.

Bref, je quitte Lexpage car ce topic soulève pleeeeein de sujets que j'aime bien, mais hésites pas à revenir poser des questions, ça m'intéresse bien de voir les étapes de ta réflexion.

Et je suis impatient de lire le retour de @trinity aussi :-)


Ce message a été modifié 2 fois. Dernière modification : 2 avril 2019 à 11:03 par Fabe.

yaug 1471 Spammeur
Pour le moment, au vu du monolithe actuel, tout le monde touche à tout. Mais vu qu'on est en train de grossir l'équipe et que l'on va avoir plusieurs poles de développements, on peut aussi envisager de rendre chaque pole responsable de parties du projet.
Comme je disais, rien n'est fait, ni décidé pour le moment, je suis là depuis 2 semaines, le nouveau CTO aussi, donc c'est justement l'occasion d'être force de proposition.
Le coup de gérer le monolythe à base de modules séparés, pour l'avoir déjà fait, c'est une complexité vite chiante pour pas grand chose je trouve.

Pour ce qui est de l'automatisation, là ça risque de pécher, on a un service infra qui est en train de migrer au fur et à mesure, et à part un docker sur lequel tout le monde ne bosse pas encore, il n'y a pas grand chose de scalable à l'heure actuelle. Sans parler du fait qu'on a pas franchement besoin d'un truc scalable vu qu'on est pas destiné au grand publique.
Mais je pense pouvoir pousser dans un second temps pour un peu d'orchestration tout de même. Mais chaque chose en son temps.

Histoire de troller un coup, pour la CI, je m'oriente vers Travis ? :angel:
trinity 230 Wookie
J'ai mis un peu tout ce qui me passait par la tête, pas mal de trucs vont se recouper avec Fabe.
Je ne vais pas trop m'attarder sur les technos per se puisque nous utilisons majoritairement des techs Microsoft (!) mais aussi des trucs développés en interne donc ils ne te seront pas utiles.
J'ai bossé sur des monolithes et sur des services pensés from scratch en microservices, donc pas directement sur une transition mais j'ai pas mal de recul sur toutes les merdes qu'on a pu avoir ;-)

Il y a évidemment plein d'avantages aux microservices, puisque tu proposes cette solution, je suppose que tu les connais déjà. Il y a aussi pas mal d'inconvénients si ce n'est pas un réel besoin.
Je vais m'attarder sur des choses auxquelles il faut prêter attention:

- Considérations design:
○ Même en designant from scratch, c'est très difficile de trouver le bon équilibre en terme de scope de chaque microservice qui te permettra d'être à jamais assez flexible pour toutes tes nouvelles features. On s'est rendu compte qu'une architecture qui semblait idéale, s'est révélée bancale lorsque d'autres requirements sont arrivés deux ans après: e.g. nouveaux patterns d'accès aux données et de flow de données.
○ Suivant tes patterns d'accès aux données et tes flows de données, tu vas peut-être devoir mettre en place plus de mécanismes de réconciliation qu'avec un monolithe (transactions qui failed quelque part dans la stack, …)
○ Suivant tes scenarios et patterns de call, les actions asynchrones vont devoir potentiellement trigger des notifications à plusieurs composants de ta stack dont tu n'avais potentiellement pas/moins besoin avec un monolithe
○ Chaque couche de ta stack de microservice implique:
§ De la latence supplémentaire qui n'est pas négligeable (même si tu es dans le même data center)
§ De la coordination entre les équipes (si les micro-services sont cross-team) pour définir les contrats d'APIs, la nécessité de maintenir une bonne doc et toujours gérer la rétrocompatibilité (versioning, …) puisque tu ne deploy pas un monolithe, attention aux rollbacks également.
§ D'avoir une bonne gestion de librairies/composants communs internes, pour éviter de tout refaire à chaque création de nouveau service. Attention cependant à la complexité potentielle d'une update de ces libs: au plus il y a de microservies, aux plus il y a de deploys à gérer (à multiplier aussi par le nombre de datacenters si tu es multi-DC)
§ Un nouveau point de failure potentiel à gérer de manière appropriée (retries/timeouts/faire surfacer les erreurs de manière adéquate vers le haut/cancellation si besoin d'autre requêtes/…)
§ Un monitoring/alerting sur la santé de tes services qui tient la route sinon tu vas pas t'en sortir s'il y en a beaucoup

- Infra/Logging/Monitoring:
○ Avoir un CI/CD et les bons TiP (test in prod) en place est indispensable - même comme ça tu vas rater des choses mais c'est une première barrière de sécurité pour ne pas tout foutre en l'air au moindre deploy
○ Un mauvais choix de techno d'infra peut amener beaucoup de sous-utilisation de chaque micro-service, et donc des coûts supplémentaires. C'est une question très difficile le bon scaling si tu n'utilises pas une techno qui le fait automatiquement (et correctement) pour toi
○ Au niveau du logging/monitoring, c'est pas toujours évident de suivre/debug une requête qui flow dans toute ta stack. Je pense en particulier à une requête qui génèrerait beaucoup de sous-requêtes dans tes microservices si tu as beaucoup de traffic. Certaines équipes chez MS utilisent le concept de Correlation Vector - je ne dis pas que tu dois mettre en place un truc aussi complexe, mais je lève juste le point.

- Sécurité:
○ Bien faire attention à toute la stack et mettre en place une auth S2S entre chaque couche et s'assurer que chaque microservice est secure
○ Splitter en microservices permet de bien déterminer les roles et quel service a accès à quoi, mais attention à la bonne gestion qui peut devenir complexe plus il y a de couches dans ta stack

Voilà voilà ce que j'ai en tête pour ce soir :-)


Ce message a été modifié 2 fois. Dernière modification : 2 avril 2019 à 19:30 par trinity.

roidelapluie 339 Maitre jedi
Bonjour,

Je droppe juste un mot:
Je recommende OpenTracing/Jaeger pour suivre les transactions à travers la stack (avec du sampling bien sur).

Répondre

Vous devez être inscrit et identifié.