# Το ταξίδι της Shoprocket προς τα microservices, μέρος 1: τι έκανα λάθος στο σπάσιμο του μονολίθου

> Άρθρο της ομάδας μηχανικών από τα πρώτα χρόνια της Shoprocket, για την πρώτη προσπάθεια εξαγωγής μιας υπηρεσίας από έναν μονόλιθο PHP. Γιατί διάλεξα λάθος πρώτη υπηρεσία, τι με δίδαξε η στενή σύζευξη και η συμβουλή του Newman που έπρεπε να είχα ακούσει νωρίτερα.

Winston Berty  - 17 Μαρτίου 2016 - 5 λεπτά ανάγνωσης

Λίγους μήνες μετά την έναρξή μου στη Shoprocket, είχα αρχίσει να απογοητεύομαι. Είχαμε μια εφαρμογή PHP στην οποία δούλευε μια μικρή ομάδα έξυπνων developers σκορπισμένων σε όλο τον κόσμο, και σε μένα φαινόταν ότι οι διορθώσεις σφαλμάτων γεννούσαν περισσότερα σφάλματα, η ενσωμάτωση νέων λειτουργιών δεν ήταν τόσο απλή όσο θα έπρεπε και οι εγκαταστάσεις (deployments) ήταν σπάνιες και αγχωτικές. Ο λόγος: ο υπερβολικά συζευγμένος κώδικας.

Είχαμε μια μονολιθική εφαρμογή, σχεδόν ολόκληρη σε ένα repository του GitHub. Οι ενημερώσεις ή οι διορθώσεις μιας λειτουργίας απαιτούσαν συχνά αλλαγές σε πολλά σημεία. Για τον έλεγχο, είχαμε μια διαδικασία peer review όπου τουλάχιστον δύο άλλοι developers έπρεπε να εγκρίνουν ένα branch πριν συγχωνευτεί στο master και γίνει deploy. Όλα αυτά σήμαιναν ότι όταν περνούσε ένα σφάλμα, ήταν συχνά δύσκολο να εντοπιστεί η αλλαγή που το προκάλεσε. Όταν τη βρίσκαμε, η διόρθωση περνούσε από την ίδια διαδικασία και ολόκληρη η εφαρμογή έπρεπε να ξαναγίνει deploy.

Ως πρόθυμος νεαρός developer που ψάχνει πάντα για το καινούργιο, όταν έπεσα πάνω στα microservices νόμισα ότι θα έλυναν όλα μας τα προβλήματα.

## Τι νόμιζα ότι ήταν τα microservices

Δεν υπάρχει επίσημος ορισμός των microservices, αλλά από την έρευνά μου κράτησα ότι η αρχιτεκτονική microservices είναι ένας τρόπος σχεδιασμού εφαρμογών λογισμικού ως κατανεμημένων συστημάτων ανεξάρτητων υπηρεσιών, καθεμιά πολύ εξειδικευμένη και με δικό της κύκλο ζωής. Για μια αναλυτική εισαγωγή, το [άρθρο](https://martinfowler.com/articles/microservices.html) του Martin Fowler είναι εξαιρετικό.

Δύο πτυχές με κέρδισαν. Πρώτα, η ιδέα να χωριστεί η εφαρμογή σε υπηρεσίες με αυστηρά όρια. Αυτό μειώνει την πιθανότητα η λογική που αφορά ένα επιχειρησιακό πλαίσιο να διαρρεύσει ανάμεσα σε συστατικά, επειδή οι διεπαφές ανάμεσα στα όρια πρέπει να σχεδιαστούν προσεκτικά. Δεν είναι τόσο απλό όσο το να κάνεις τοπικές κλήσεις συναρτήσεων. Δεύτερον, κάθε συστατικό μπορεί να έχει τον δικό του ανεξάρτητο κύκλο ζωής. Οι ομάδες μπορούν να κατέχουν τον κώδικά τους και να χρησιμοποιούν τη στοίβα που ταιριάζει καλύτερα στην υπηρεσία, ενώ οι αλλαγές μπορούν να γίνονται deploy μία υπηρεσία τη φορά και να αναιρούνται χωρίς να επηρεάζονται οι υπόλοιπες.

Είχα πειστεί. Η Shoprocket θα έσπαγε τον μονόλιθο. Αυτό είναι το μέρος 1 μιας σύντομης σειράς που ακολουθεί το ταξίδι. Ελπίζω οι αναγνώστες που σχεδιάζουν ή περνούν μια παρόμοια μετάβαση να μάθουν από τις επιτυχίες και τις αποτυχίες μας.

## Η πρώτη πρόκληση ήταν ανθρώπινη, όχι τεχνική

Έπρεπε να πουλήσω την ιδέα στην υπόλοιπη ομάδα. Ήταν περίεργοι αλλά δεν μοιράζονταν τον ενθουσιασμό και δίσταζαν να δώσουν ώρες ανάπτυξης σε αυτό το πρώιμο στάδιο της ζωής του προϊόντος. Ευτυχώς, ο CTO ήθελε να ψάξω τη διαχείριση των sessions μας, οπότε άδραξα την ευκαιρία: τον έπεισα ότι μπορούσα να αποσπάσω μια υπηρεσία sessions.

Εκ των υστέρων, ήταν κακή επιλογή για πρώτη υπηρεσία. Το προϊόν μας περιλαμβάνει ένα widget JavaScript που [ενεργοποιεί το ηλεκτρονικό εμπόριο σε οποιοδήποτε site](https://v3.shoprocket.io/el/features/sell-on-any-website.md). Αντιμετωπίζουμε τα sessions ως πόρο, αποθηκεύοντας πληροφορίες session στη βάση δεδομένων για την ανάλυση της εγκατάλειψης καλαθιού και άλλων KPIs. Αλλά αυτός ο πόρος δεν είναι τόσο απτός όσο οι παραγγελίες ή οι γραμμές παραγγελίας, και χρησιμοποιούσαμε sessions σε σχεδόν κάθε αλλαγή κατάστασης της εφαρμογής. Αυτό σήμαινε ότι η υπηρεσία θα «μιλούσε» αναπόφευκτα πολύ με την υπόλοιπη εφαρμογή, κάτι που δεν είχα προβλέψει και που δυσκόλεψε τη δουλειά μου.

## Τι έμαθα χτίζοντάς το στην πράξη

Εντατικοποίησα την έρευνά μου. Δίπλα στον Fowler, το **Building Microservices** του Sam Newman αποδείχθηκε απαραίτητη πηγή.

Η συμβουλή του Newman, εκ των υστέρων, ήταν αυτή που έπρεπε να είχα ακολουθήσει: πρώτα αναδιαρθρώστε την υπάρχουσα εφαρμογή σε modules που αντανακλούν τα οριοθετημένα πλαίσια (bounded contexts) του domain. Όταν οι developers είναι ικανοποιημένοι με τα όρια, *τότε* αποσπάτε τα modules σε δικές τους υπηρεσίες. Ο λόγος είναι ότι είναι πολύ πιο εύκολο να διασπάσετε και να ξαναγράψετε modules με κακά όρια παρά ολόκληρες υπηρεσίες με όλον τον επιπλέον κώδικα υποδομής και τους μόνιμους πόρους τους.

Δεν ακολούθησα αυτή τη συμβουλή. Πρόθυμος να χτίσω ένα δικό μου συστατικό, προχώρησα με την υπηρεσία sessions.

Διάλεξα μια στοίβα ελάχιστα διαφορετική από του μονόλιθου και άρχισα να χτίζω. Η ίδια η υπηρεσία στήθηκε γρήγορα, χρειάστηκαν λίγες εβδομάδες για μια αυτόνομη εφαρμογή με REST API. Εκεί δεν ήταν το δύσκολο. Το δύσκολο ήταν να κάνω την υπηρεσία να μιλήσει με τον μονόλιθο.

Η διαχείριση sessions αποδείχθηκε στενά συζευγμένη με τον υπόλοιπο κώδικα. Η αντικατάσταση κλήσεων συναρτήσεων με κλήσεις API ήταν αργή δουλειά. Επειδή η υπηρεσία sessions και ο μονόλιθος είχαν ξεχωριστά σχήματα βάσης δεδομένων, έπρεπε να ξαναγράψω κάθε λογική στον μονόλιθο που χρησιμοποιούσε πόρους session από την παλιά βάση, αναδιαρθρώνοντας τα δεδομένα στο όριο της εφαρμογής ώστε πελάτες όπως το widget JavaScript να παραμένουν συμβατοί.

Η ενσωμάτωση πήρε περισσότερο χρόνο από το χτίσιμο. Και αυτό δεν περιλάμβανε ακόμη το μεγαλύτερο μέρος του επιπλέον φόρτου που φέρνουν συνήθως τα microservices: service discovery, logging, monitoring, distributed tracing. Χειρότερα, η στενή σύζευξη σήμαινε ότι οι αλλαγές απλώνονταν σε πολλές περιοχές του κώδικα. Καθώς η ομάδα δούλευε παράλληλα εκείνη την περίοδο, η συγχώνευση και η μεταφορά της υπηρεσίας sessions στην παραγωγή θα απαιτούσε πολύ περισσότερο συντονισμό από όσο είχα υπολογίσει.

## Η ειλικρινής αποτίμηση

Η υπηρεσία μπορεί σύντομα να πάει στην παραγωγή. Αλλά τώρα νιώθω ότι έπρεπε να έχω ακολουθήσει τη συμβουλή του Newman και να είχα επενδύσει την προσπάθειά μου πρώτα στην αρθρωτή οργάνωση της υπάρχουσας εφαρμογής. Το όφελος μιας μεμονωμένης υπηρεσίας που ζει μόνη της είναι οριακό. Το πραγματικό όφελος έρχεται από το σπάσιμο ολόκληρου του συστήματος, τουλάχιστον σε χονδρόκοκκες υπηρεσίες που μιλούν όσο το δυνατόν λιγότερο μεταξύ τους. Αυτό απαιτεί καλά μελετημένα όρια συστατικών, και δεν είχαμε φτάσει ακόμη εκεί.

Εξακολουθώ να πιστεύω στα microservices ως ιδέα. Βλέπω την προσπάθειά μου ως ένα χρήσιμο πείραμα. Έμαθα πάρα πολλά για την αρχιτεκτονική εφαρμογών, τη μοντελοποίηση του domain και τις αρχές REST, και αυτά τα μαθήματα είχαν αλυσιδωτά αποτελέσματα σε άλλα μέρη του κώδικά μας.

Για όποιον σκέφτεται μια παρόμοια μετάβαση, οι ειλικρινείς συστάσεις μου:

- Διαβάστε όσο περισσότερο γίνεται για το θέμα πριν δεσμευτείτε
- Αναβάλετε τη δουλειά μέχρι να νιώθετε πραγματικά σίγουροι με την υπάρχουσα βάση κώδικα και το μοντέλο του domain σας
- Θυμηθείτε ότι υπάρχουν κι άλλοι τρόποι να φέρετε σταθερότητα και ανθεκτικότητα σε έναν μονόλιθο. Οι αυτοματοποιημένες δοκιμές μονάδας και λειτουργικές δοκιμές βοηθούν τεράστια. Η ανάπτυξη καθοδηγούμενη από δοκιμές (TDD) μειώνει τις παλινδρομήσεις. Η οριζόντια κλιμάκωση κάνει τις εγκαταστάσεις λιγότερο επώδυνες
- Ξεκινήστε οργανώνοντας τον μονόλιθο σε modules πριν αποσπάσετε υπηρεσίες

Η Shoprocket θα συνεχίσει το ταξίδι της. Το μέρος 2 είναι εκεί που γίνεται πιο ενδιαφέρον.

---

*Δημοσιεύτηκε αρχικά ως το πρώτο μιας σύντομης σειράς που καταγράφει την πρώιμη μετάβαση της Shoprocket μακριά από έναν μονόλιθο PHP. Το πλήρες ταξίδι, μαζί με τα λάθη που διορθώθηκαν σε επόμενες επαναλήψεις, συνεχίστηκε σε κάθε μεγάλη επανεγγραφή της πλατφόρμας από τότε.*

---

- HTML version: https://v3.shoprocket.io/el/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith
- Language: Ελληνικά (el)
- Also in: [العربية](https://v3.shoprocket.io/ar/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Deutsch](https://v3.shoprocket.io/de/blog/shoprocket-microservices-teil-1-monolith-zerlegen-fehler.md), [English](https://v3.shoprocket.io/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Español](https://v3.shoprocket.io/es/blog/shoprocket-microservicios-parte-1-lo-que-hice-mal-monolito.md), [Français](https://v3.shoprocket.io/fr/blog/shoprocket-vers-les-microservices-partie-1-decouper-le-monolithe.md), [עברית](https://v3.shoprocket.io/he/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [हिन्दी](https://v3.shoprocket.io/hi/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Bahasa Indonesia](https://v3.shoprocket.io/id/blog/perjalanan-shoprocket-menuju-microservices-bagian-1-salah-memecah-monolit.md), [Italiano](https://v3.shoprocket.io/it/blog/viaggio-di-shoprocket-verso-i-microservizi-parte-1-cosa-ho-sbagliato-sul-monolite.md), [日本語](https://v3.shoprocket.io/ja/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Lietuvių](https://v3.shoprocket.io/lt/tinklarastis/shoprocket-kelione-i-mikropaslaugas-1-dalis.md), [Norsk](https://v3.shoprocket.io/nb/blogg/shoprockets-vei-mot-mikrotjenester-del-1-hva-jeg-tok-feil-av.md), [Nederlands](https://v3.shoprocket.io/nl/blog/shoprocket-microservices-deel-1-monoliet-opknippen.md), [Polski](https://v3.shoprocket.io/pl/blog/droga-shoprocket-do-mikroserwisow-czesc-1-rozbijanie-monolitu.md), [Português](https://v3.shoprocket.io/pt/blog/jornada-do-shoprocket-para-microsservicos-parte-1-o-que-errei-ao-quebrar-o-monolito.md), [Română](https://v3.shoprocket.io/ro/blog/drumul-shoprocket-spre-microservicii-partea-1-ce-am-gresit-cu-monolitul.md), [Русский](https://v3.shoprocket.io/ru/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [ไทย](https://v3.shoprocket.io/th/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md), [Türkçe](https://v3.shoprocket.io/tr/blog/shoprocket-mikroservis-yolculugu-1-monoliti-parcalarken-yanlis-yaptiklarim.md), [中文](https://v3.shoprocket.io/zh/blog/shoprockets-journey-to-microservices-part-1-what-i-got-wrong-about-breaking-up-the-monolith.md)
