découpe du monolithe
Du monolithe aux microservices : le premier service sorti en 20 jours
Onze ans de commits dans un seul déployable, quatre cents tables dans un seul schéma, un train de release qui part une fois par trimestre. Nous trouvons où les données se séparent vraiment, découpons le schéma en premier, et sortons un service qui se compile, se déploie et réveille sa propre astreinte. Rails, Django, Spring, .NET, PHP ou Go : la méthode est la même, et le deuxième service va plus vite parce que le plus dur est derrière vous.
20 jours pour le premier service, plus vite pour le deuxième
Deux services et une bibliothèque. Le nombre de services devrait correspondre au nombre d'équipes capables d'en porter l'astreinte.
Un déployable
Un dépôt, un schéma, un train de release, des imports qui tournent en rond.
- one deployable11 years of commits
- shared schema400+ tables
- release trainquarterly
- circular importscycles
Découpé
Deux services avec leurs propres schémas, une bibliothèque pour le partagé, des déploiements séparés.
- billingGo · own schema
- catalogueGo · own schema
- shared kernellibrary
- deploysper service
20 jours pour le premier service, plus vite pour le deuxième
Comment le travail se déroule
- 01jours 1–4
Trouver les coutures dans les données
Les logs de requêtes montrent quelles tables sont lues ensemble dans la même requête. C'est là que sont les frontières, quoi qu'en dise la structure des packages.
- 02jours 3–8
Séparer le schéma d'abord
Découper les tables et retirer les jointures qui traversent la frontière pendant que tout est encore un seul déployable. L'essentiel du risque vit dans cette étape, et à ce stade c'est encore réversible.
- 03jours 8–15
Extraire un service
Celui qui a le moins de dépendances entrantes, rarement celui qui agace le plus de monde. Il part derrière la même interface jusqu'à ce que le faire tourner cesse d'être intéressant.
- 04jours 14–20
Lui donner sa propre chaîne
Dépôt à lui, déploiement à lui, astreinte à lui. Un service dont les livraisons doivent encore être coordonnées avec le monolithe ne vous a rien gagné, et cela se voit au quinzième jour plutôt qu'à la fin.
Ce que fait la plateforme, ce que fait un humain
| Ce que fait la plateforme, ce que fait un humain | Qui fait quoi | Notes |
|---|---|---|
| Cartographier les co-accès aux tables et le couplage des modules | Plateforme | Depuis les logs de requêtes et le graphe d'appels, sur une période assez longue pour inclure une clôture mensuelle. |
| Proposer les coutures | Les deux | La plateforme classe les candidates. Un humain les confronte aux frontières de vos équipes. |
| Casser les jointures qui traversent la frontière | Plateforme | Travail mécanique, relu en merge requests, livré en petits morceaux. |
| Choisir quel service part en premier | Ingénieur | L'appartenance à une équipe décide de cela plus souvent que le code. |
| Les frontières transactionnelles | Ingénieur | Là où une transaction traversait la couture, quelqu'un doit décider ce qui se passe en cas d'échec. |
| CI, déploiement et astreinte | Les deux | Un service sans sa propre chaîne et sa propre astreinte est un module avec des sauts réseau en plus. |
Qui coupe la couture
Des dizaines de migrations, plus de dix ans sur des systèmes bâtis par des gens partis depuis, et assez de découpages pour savoir lesquels rapportent. Des monolithes Rails, Django, Spring, .NET, PHP et Go, des schémas à quatre cents tables et dix ans de jointures qui traversent les frontières. La couture n'est jamais là où le schéma d'architecture la place, et trouver la vraie est l'essentiel de ce que vous achetez.
La première extraction est le test, et elle est bornée : un service, son propre schéma, son propre déploiement, en production. Vous obtenez une réponse qui tourne pour le prix d'une seule phase.
Questions que nous posent les ingénieurs
- Combien de services devrions-nous avoir au bout ?
- Moins que sur le schéma de la présentation d'architecture. Extrayez-en un, faites-le tourner en production un trimestre, puis décidez du suivant. Les équipes qui en planifient douze d'avance en obtiennent quatre et beaucoup de base de données partagée.
- Faut-il réécrire en Go ?
- Non. Extraire et réécrire sont deux décisions séparées, et beaucoup de découpages restent dans le langage d'origine. Là où nous réécrivons un service, c'est parce que ce module allait être réécrit de toute façon, où qu'il vive.
- Que devient le code partagé ?
- Il devient une bibliothèque versionnée à petite surface. Quand le noyau partagé se met à grossir à chaque sprint, c'est le signal que votre couture était au mauvais endroit, et il est bien moins cher de la déplacer au quinzième jour qu'à la deuxième année.
- Peut-on faire cela tout en livrant des fonctionnalités ?
- Oui, et ce sera plus lent. L'étape à protéger est la séparation du schéma : y intercaler du travail fonctionnel est la façon dont ces projets s'enlisent un an avec la base à moitié découpée.
- Et la base de données partagée dont tout le monde nous met en garde ?
- C'est pour cela que le schéma passe en premier. Deux services sur un même schéma forment un monolithe distribué avec des modes de panne pires qu'au départ, et c'est la façon la plus courante de mal faire ce travail.
Commencez par une extraction
La taille, le rythme de livraison et ce qui force le changement suffisent pour une première réponse. Nous revenons avec l'endroit où les coutures semblent passer et ce que demanderait le premier service.
Un ingénieur répond, et la première question porte normalement sur votre rythme de livraison.