Monolith aufteilen
Monolith zu Microservices: der erste Service in 20 Tagen
Elf Jahre Commits in einem Deployable, vierhundert Tabellen in einem Schema, ein Release-Zug, der einmal im Quartal abfährt. Wir finden, wo die Daten wirklich auseinandergehen, trennen zuerst das Schema und schneiden einen Service heraus, der für sich baut, deployt und alarmiert. Rails, Django, Spring, .NET, PHP oder Go: Die Methode ist dieselbe, und der zweite Service geht schneller, weil der harte Teil hinter Ihnen liegt.
20 Tage für den ersten Service, schneller beim zweiten
Zwei Services und eine Bibliothek. Die Zahl der Services sollte zur Zahl der Teams passen, die dafür Bereitschaft tragen können.
Ein Deployable
Ein Repository, ein Schema, ein Release-Zug, Importe, die im Kreis laufen.
- one deployable11 years of commits
- shared schema400+ tables
- release trainquarterly
- circular importscycles
Geteilt
Zwei Services mit eigenen Schemata, eine Bibliothek für das Gemeinsame, getrennte Deploys.
- billingGo · own schema
- catalogueGo · own schema
- shared kernellibrary
- deploysper service
20 Tage für den ersten Service, schneller beim zweiten
Wie die Arbeit läuft
- 01Tag 1–4
Die Nähte in den Daten finden
Query-Logs zeigen, welche Tabellen im selben Request zusammen gelesen werden. Dort liegen die Grenzen, was auch immer die Paketstruktur behauptet.
- 02Tag 3–8
Zuerst das Schema trennen
Tabellen aufteilen und die Joins über die Grenze entfernen, solange alles noch ein Deployable ist. Das meiste Risiko liegt in diesem Schritt, und in diesem Stadium ist er noch umkehrbar.
- 03Tag 8–15
Einen Service herausziehen
Den mit den wenigsten eingehenden Abhängigkeiten, und das ist selten der, der am meisten nervt. Er läuft hinter derselben Schnittstelle, bis der Betrieb langweilig wird.
- 04Tag 14–20
Ihm eine eigene Pipeline geben
Eigenes Repository, eigener Deploy, eigene Bereitschaft. Wenn Releases weiterhin mit dem Monolithen abgestimmt werden müssen, war nichts gewonnen, und das zeigt sich an Tag fünfzehn und nicht am Ende.
Was die Plattform macht, was ein Mensch macht
| Was die Plattform macht, was ein Mensch macht | Wer macht was | Anmerkungen |
|---|---|---|
| Gemeinsame Tabellenzugriffe und Modulkopplung kartieren | Plattform | Aus Query-Logs und dem Aufrufgraphen, über einen Zeitraum, der den Monatsabschluss einschließt. |
| Die Nähte vorschlagen | Gemeinsam | Die Plattform sortiert die Kandidaten. Ein Mensch prüft sie gegen Ihre Teamgrenzen. |
| Die Joins über die Grenze auflösen | Plattform | Mechanische Arbeit, als Pull Requests geprüft, in kleinen Stücken ausgeliefert. |
| Wählen, welcher Service zuerst geht | Entwickler | Wem was gehört, entscheidet das öfter als der Code. |
| Transaktionsgrenzen | Entwickler | Wo eine Datenbanktransaktion früher über die Naht ging, muss jemand entscheiden, was im Fehlerfall passiert. |
| CI, Deploy und Bereitschaft | Gemeinsam | Ein Service ohne eigene Pipeline und eigene Bereitschaft ist ein Modul mit zusätzlichen Netzwerksprüngen. |
Wer die Naht schneidet
Dutzende Migrationen, über zehn Jahre an Systemen, die von längst gegangenen Leuten gebaut wurden, und genug Aufteilungen, um zu wissen, welche sich auszahlen. Monolithen in Rails, Django, Spring, .NET, PHP und Go, Schemata mit vierhundert Tabellen und zehn Jahren Joins über die Grenze. Die Naht liegt nie dort, wo das Architekturdiagramm sie zeichnet, und die echte zu finden ist das meiste, was Sie einkaufen.
Die erste Extraktion ist die Prüfung, und sie ist abgegrenzt: ein Service, eigenes Schema, eigener Deploy, im Produktivbetrieb. Sie bekommen eine belastbare Antwort zum Preis einer Phase.
Fragen, die Entwickler uns stellen
- Mit wie vielen Services sollten wir enden?
- Mit weniger als im Diagramm der Architekturpräsentation. Ziehen Sie einen heraus, betreiben Sie ihn ein Quartal im Produktivbetrieb und entscheiden Sie dann über den nächsten. Teams, die vorab zwölf planen, bekommen meist vier und viel gemeinsame Datenbank.
- Müssen wir in Go neu schreiben?
- Nein. Extraktion und Neuschreiben sind getrennte Entscheidungen, und viele Aufteilungen bleiben in der ursprünglichen Sprache. Wo wir einen Service doch neu schreiben, lag es daran, dass dieses Modul ohnehin neu geschrieben worden wäre, egal wo es gewohnt hätte.
- Was passiert mit gemeinsam genutztem Code?
- Er wird eine versionierte Bibliothek mit kleiner Oberfläche. Wenn der gemeinsame Kern in jedem Sprint wächst, ist das das Signal, dass die Naht an der falschen Stelle lag, und sie früh im Projekt zu verschieben kostet einen Bruchteil dessen, was sie im zweiten Jahr kostet.
- Geht das, während wir Features liefern?
- Ja, und es wird dadurch langsamer. Zu schützen ist der Schritt der Schematrennung: Feature-Arbeit dort dazwischenzuschieben ist der Weg, auf dem diese Projekte ein Jahr lang mit halb geteilter Datenbank stehenbleiben.
- Was ist mit der gemeinsamen Datenbank, vor der alle warnen?
- Deshalb kommt das Schema zuerst. Zwei Services auf einem Schema sind ein verteilter Monolith mit schlechteren Fehlerbildern als der Ausgangszustand, und das ist die häufigste Art, diese Arbeit schlecht zu machen.
Fangen Sie mit einer Extraktion an
Größe, Release-Frequenz und das, was die Änderung erzwingt, reichen für eine erste Antwort. Wir kommen damit zurück, wo die Nähte zu liegen scheinen und was der erste Service kosten würde.
Ein Entwickler antwortet, und die erste Frage gilt normalerweise Ihrer Release-Frequenz.