Σε αυτό το άρθρο, θα μιλήσω για το πώς το έργο στο οποίο εργάζομαι μετατράπηκε από ένα μεγάλο μονόλιθο σε ένα σύνολο μικροϋπηρεσιών.
Το έργο ξεκίνησε την ιστορία του πριν από πολύ καιρό, στις αρχές του 2000. Οι πρώτες εκδόσεις γράφτηκαν σε Visual Basic 6. Με τον καιρό, έγινε σαφές ότι η ανάπτυξη σε αυτή τη γλώσσα θα ήταν δύσκολο να υποστηριχθεί στο μέλλον, καθώς το IDE και η ίδια η γλώσσα είναι ελάχιστα ανεπτυγμένη. Στα τέλη της δεκαετίας του 2000, αποφασίστηκε η μετάβαση στο πιο πολλά υποσχόμενο C#. Η νέα έκδοση γράφτηκε παράλληλα με την αναθεώρηση της παλιάς, σταδιακά όλο και περισσότερος κώδικας γράφτηκε στο .NET. Το Backend στη C# αρχικά επικεντρώθηκε σε μια αρχιτεκτονική υπηρεσίας, αλλά κατά την ανάπτυξη, χρησιμοποιήθηκαν κοινές βιβλιοθήκες με λογική και οι υπηρεσίες ξεκίνησαν σε μια ενιαία διαδικασία. Το αποτέλεσμα ήταν μια εφαρμογή που ονομάσαμε «μονόλιθος υπηρεσιών».
Ένα από τα λίγα πλεονεκτήματα αυτού του συνδυασμού ήταν η δυνατότητα των υπηρεσιών να καλούν η μία την άλλη μέσω ενός εξωτερικού API. Υπήρχαν σαφείς προϋποθέσεις για τη μετάβαση σε μια πιο σωστή υπηρεσία, και στο μέλλον, αρχιτεκτονική microservice.
Ξεκινήσαμε τις εργασίες μας για την αποσύνθεση γύρω στο 2015. Δεν έχουμε φτάσει ακόμη σε μια ιδανική κατάσταση - υπάρχουν ακόμη τμήματα ενός μεγάλου έργου που δύσκολα μπορούν να ονομαστούν μονόλιθοι, αλλά δεν μοιάζουν ούτε με μικροϋπηρεσίες. Ωστόσο, η πρόοδος είναι σημαντική.
Θα μιλήσω για αυτό στο άρθρο.

περιεχόμενο
Αρχιτεκτονική και προβλήματα της υπάρχουσας λύσης
Αρχικά, η αρχιτεκτονική φαινόταν ως εξής: το UI είναι μια ξεχωριστή εφαρμογή, το μονολιθικό μέρος είναι γραμμένο σε Visual Basic 6, η εφαρμογή .NET είναι ένα σύνολο σχετικών υπηρεσιών που λειτουργούν με μια αρκετά μεγάλη βάση δεδομένων.
Μειονεκτήματα της προηγούμενης λύσης
Μοναδικό σημείο αποτυχίας
Είχαμε ένα μόνο σημείο αποτυχίας: η εφαρμογή .NET εκτελέστηκε σε μία μόνο διαδικασία. Εάν κάποια λειτουργική μονάδα απέτυχε, ολόκληρη η εφαρμογή απέτυχε και έπρεπε να επανεκκινηθεί. Δεδομένου ότι αυτοματοποιούμε μεγάλο αριθμό διαδικασιών για διαφορετικούς χρήστες, λόγω αποτυχίας σε έναν από αυτούς, όλοι δεν μπορούσαν να λειτουργήσουν για κάποιο χρονικό διάστημα. Και σε περίπτωση σφάλματος λογισμικού, ακόμη και η δημιουργία αντιγράφων ασφαλείας δεν βοήθησε.
Ουρά βελτιώσεων
Αυτό το μειονέκτημα είναι μάλλον οργανωτικό. Η εφαρμογή μας έχει πολλούς πελάτες και όλοι θέλουν να τη βελτιώσουν το συντομότερο δυνατό. Προηγουμένως, ήταν αδύνατο να γίνει αυτό παράλληλα και όλοι οι πελάτες στέκονταν στην ουρά. Αυτή η διαδικασία ήταν αρνητική για τις επιχειρήσεις γιατί έπρεπε να αποδείξουν ότι το έργο τους ήταν πολύτιμο. Και η ομάδα ανάπτυξης ξόδεψε χρόνο οργανώνοντας αυτήν την ουρά. Αυτό πήρε πολύ χρόνο και προσπάθεια, και το προϊόν τελικά δεν μπορούσε να αλλάξει όσο γρήγορα θα ήθελαν.
Μη βέλτιστη χρήση πόρων
Κατά τη φιλοξενία υπηρεσιών σε μια μεμονωμένη διαδικασία, πάντα αντιγράφαμε πλήρως τη διαμόρφωση από διακομιστή σε διακομιστή. Θέλαμε να τοποθετήσουμε τις πιο φορτωμένες υπηρεσίες ξεχωριστά, ώστε να μην σπαταλήσουμε πόρους και να αποκτήσουμε πιο ευέλικτο έλεγχο στο πρόγραμμα ανάπτυξης.
Δύσκολη η εφαρμογή σύγχρονων τεχνολογιών
Ένα πρόβλημα γνωστό σε όλους τους προγραμματιστές: υπάρχει η επιθυμία να εισαχθούν σύγχρονες τεχνολογίες στο έργο, αλλά δεν υπάρχει ευκαιρία. Με μια μεγάλη μονολιθική λύση, οποιαδήποτε ενημέρωση της τρέχουσας βιβλιοθήκης, για να μην αναφέρουμε τη μετάβαση σε μια νέα, μετατρέπεται σε μια μάλλον μη τετριμμένη εργασία. Χρειάζεται πολύς χρόνος για να αποδείξετε στον αρχηγό της ομάδας ότι αυτό θα φέρει περισσότερα μπόνους παρά χαμένα νεύρα.
Δυσκολία έκδοσης αλλαγών
Αυτό ήταν το πιο σοβαρό πρόβλημα - κυκλοφορούσαμε εκδόσεις κάθε δύο μήνες.
Κάθε κυκλοφορία μετατράπηκε σε πραγματική καταστροφή για την τράπεζα, παρά τις δοκιμές και τις προσπάθειες των προγραμματιστών. Η επιχείρηση κατάλαβε ότι στις αρχές της εβδομάδας κάποιες από τις λειτουργίες της δεν θα λειτουργούσαν. Και οι προγραμματιστές κατάλαβαν ότι τους περίμενε μια εβδομάδα σοβαρών περιστατικών.
Όλοι είχαν την επιθυμία να αλλάξουν την κατάσταση.
Προσδοκίες από τις μικροϋπηρεσίες
Έκδοση εξαρτημάτων όταν είναι έτοιμα. Παράδοση των συστατικών όταν είναι έτοιμα με αποσύνθεση του διαλύματος και διαχωρισμό διαφορετικών διεργασιών.
Μικρές ομάδες προϊόντων. Αυτό είναι σημαντικό γιατί μια μεγάλη ομάδα που εργαζόταν στον παλιό μονόλιθο ήταν δύσκολο να διαχειριστεί. Μια τέτοια ομάδα αναγκάστηκε να εργαστεί σύμφωνα με μια αυστηρή διαδικασία, αλλά ήθελε περισσότερη δημιουργικότητα και ανεξαρτησία. Μόνο μικρές ομάδες μπορούσαν να το αντέξουν οικονομικά.
Απομόνωση υπηρεσιών σε ξεχωριστές διαδικασίες. Ιδανικά, θα ήθελα να το απομονώσω σε κοντέινερ, αλλά ένας μεγάλος αριθμός υπηρεσιών που είναι γραμμένες στο .NET Framework εκτελούνται μόνο υπό WindowsΥπηρεσίες που βασίζονται στο .NET Core εμφανίζονται τώρα, αλλά εξακολουθούν να υπάρχουν λίγες από αυτές.
Ευελιξία ανάπτυξης. Θα θέλαμε να συνδυάσουμε τις υπηρεσίες με τον τρόπο που τις χρειαζόμαστε και όχι με τον τρόπο που τις επιβάλλει ο κώδικας.
Χρήση νέων τεχνολογιών. Αυτό είναι ενδιαφέρον για κάθε προγραμματιστή.
Προβλήματα μετάβασης
Φυσικά, αν ήταν εύκολο να σπάσεις ένα μονόλιθο σε μικροϋπηρεσίες, δεν θα χρειαζόταν να μιλάμε για αυτό σε συνέδρια και να γράφουμε άρθρα. Υπάρχουν πολλές παγίδες σε αυτή τη διαδικασία. Θα περιγράψω τις κυριότερες που μας εμπόδισαν.
Το πρώτο πρόβλημα τυπικό για τους περισσότερους μονόλιθους: συνοχή της επιχειρηματικής λογικής. Όταν γράφουμε ένα μονόλιθο, θέλουμε να επαναχρησιμοποιούμε τις τάξεις μας για να μην γράφουμε περιττό κώδικα. Και όταν μεταβαίνετε σε μικροϋπηρεσίες, αυτό γίνεται πρόβλημα: όλος ο κώδικας είναι αρκετά στενά συνδεδεμένος και είναι δύσκολο να διαχωριστούν οι υπηρεσίες.
Κατά την έναρξη των εργασιών, το αποθετήριο είχε περισσότερα από 500 έργα και περισσότερες από 700 χιλιάδες γραμμές κώδικα. Αυτή είναι μια αρκετά μεγάλη απόφαση και δεύτερο πρόβλημα. Δεν ήταν δυνατόν απλά να το πάρουμε και να το χωρίσουμε σε μικροϋπηρεσίες.
Τρίτο πρόβλημα — έλλειψη απαραίτητων υποδομών. Στην πραγματικότητα, αντιγράφαμε χειροκίνητα τον πηγαίο κώδικα στους διακομιστές.
Πώς να μεταβείτε από το monolith στις microservices
Παροχή μικροϋπηρεσιών
Πρώτον, προσδιορίσαμε αμέσως μόνοι μας ότι ο διαχωρισμός των μικροϋπηρεσιών είναι μια επαναληπτική διαδικασία. Πάντα μας ζητούσαν να αναπτύσσουμε παράλληλα επιχειρηματικά προβλήματα. Το πώς θα το εφαρμόσουμε τεχνικά είναι ήδη δικό μας πρόβλημα. Ως εκ τούτου, προετοιμαστήκαμε για μια επαναληπτική διαδικασία. Δεν θα λειτουργήσει αλλιώς εάν έχετε μια μεγάλη εφαρμογή και δεν είναι αρχικά έτοιμη να ξαναγραφτεί.
Ποιες μεθόδους χρησιμοποιούμε για να απομονώσουμε τις μικροϋπηρεσίες;
Ο πρώτος τρόπος — μετακινήστε υπάρχουσες μονάδες ως υπηρεσίες. Από αυτή την άποψη, ήμασταν τυχεροί: υπήρχαν ήδη καταχωρημένες υπηρεσίες που λειτουργούσαν χρησιμοποιώντας το πρωτόκολλο WCF. Χωρίστηκαν σε ξεχωριστές συνελεύσεις. Τα μεταφέραμε ξεχωριστά, προσθέτοντας έναν μικρό εκκινητή σε κάθε κατασκευή. Γράφτηκε χρησιμοποιώντας την υπέροχη βιβλιοθήκη Topshelf, η οποία σας επιτρέπει να εκτελείτε την εφαρμογή τόσο ως υπηρεσία όσο και ως κονσόλα. Αυτό είναι βολικό για τον εντοπισμό σφαλμάτων, καθώς δεν απαιτούνται πρόσθετα έργα στη λύση.
Οι υπηρεσίες συνδέονταν σύμφωνα με την επιχειρηματική λογική, αφού χρησιμοποιούσαν κοινές συναρμολογήσεις και δούλευαν με μια κοινή βάση δεδομένων. Δύσκολα θα μπορούσαν να ονομαστούν μικροϋπηρεσίες στην καθαρή τους μορφή. Ωστόσο, θα μπορούσαμε να παρέχουμε αυτές τις υπηρεσίες χωριστά, σε διαφορετικές διαδικασίες. Αυτό και μόνο κατέστησε δυνατή τη μείωση της επιρροής τους μεταξύ τους, μειώνοντας το πρόβλημα με παράλληλη ανάπτυξη και ένα μόνο σημείο αποτυχίας.
Η συναρμολόγηση με τον κεντρικό υπολογιστή είναι μόνο μία γραμμή κώδικα στην κατηγορία Program. Κρύψαμε δουλειά με το Topshelf σε μια βοηθητική τάξη.
namespace RBA.Services.Accounts.Host
{
internal class Program
{
private static void Main(string[] args)
{
HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");
}
}
}
Ο δεύτερος τρόπος κατανομής μικροϋπηρεσιών είναι: δημιουργήστε τα για να λύσετε νέα προβλήματα. Εάν ταυτόχρονα ο μονόλιθος δεν μεγαλώνει, αυτό είναι ήδη εξαιρετικό, πράγμα που σημαίνει ότι κινούμαστε προς τη σωστή κατεύθυνση. Για την επίλυση νέων προβλημάτων, προσπαθήσαμε να δημιουργήσουμε ξεχωριστές υπηρεσίες. Εάν υπήρχε μια τέτοια ευκαιρία, τότε δημιουργήσαμε περισσότερες «κανονικές» υπηρεσίες που διαχειρίζονται πλήρως το δικό τους μοντέλο δεδομένων, μια ξεχωριστή βάση δεδομένων.
Εμείς, όπως πολλοί, ξεκινήσαμε με υπηρεσίες ελέγχου ταυτότητας και εξουσιοδότησης. Είναι τέλεια για αυτό. Είναι ανεξάρτητοι, κατά κανόνα, έχουν ξεχωριστό μοντέλο δεδομένων. Οι ίδιοι δεν αλληλεπιδρούν με το μονόλιθο, μόνο στρέφεται σε αυτούς για να λύσουν κάποια προβλήματα. Χρησιμοποιώντας αυτές τις υπηρεσίες, μπορείτε να ξεκινήσετε τη μετάβαση σε μια νέα αρχιτεκτονική, να διορθώσετε την υποδομή σε αυτές, να δοκιμάσετε κάποιες προσεγγίσεις που σχετίζονται με βιβλιοθήκες δικτύου κ.λπ. Δεν έχουμε ομάδες στον οργανισμό μας που δεν θα μπορούσαν να δημιουργήσουν μια υπηρεσία ελέγχου ταυτότητας.
Ο τρίτος τρόπος κατανομής μικροϋπηρεσιώνΑυτό που χρησιμοποιούμε είναι λίγο συγκεκριμένο για εμάς. Αυτή είναι η αφαίρεση της επιχειρηματικής λογικής από το επίπεδο διεπαφής χρήστη. Η κύρια εφαρμογή διεπαφής χρήστη είναι επιτραπέζιος, όπως και το backend, είναι γραμμένη σε C#. Οι προγραμματιστές έκαναν περιοδικά λάθη και μετέφεραν τμήματα λογικής στη διεπαφή χρήστη που θα έπρεπε να υπήρχαν στο backend και να επαναχρησιμοποιηθούν.
Εάν κοιτάξετε ένα πραγματικό παράδειγμα από τον κώδικα του τμήματος διεπαφής χρήστη, μπορείτε να δείτε ότι το μεγαλύτερο μέρος αυτής της λύσης περιέχει πραγματική επιχειρηματική λογική που είναι χρήσιμη σε άλλες διαδικασίες, όχι μόνο για τη δημιουργία της φόρμας διεπαφής χρήστη.

Η πραγματική λογική διεπαφής χρήστη υπάρχει μόνο στις τελευταίες δύο γραμμές. Το μεταφέραμε στον διακομιστή για να μπορέσει να χρησιμοποιηθεί ξανά, μειώνοντας έτσι το UI και επιτυγχάνοντας τη σωστή αρχιτεκτονική.
Ο τέταρτος και πιο σημαντικός τρόπος απομόνωσης μικροϋπηρεσιών, που καθιστά δυνατή τη μείωση του μονόλιθου, είναι η αφαίρεση των υπαρχουσών υπηρεσιών με επεξεργασία. Όταν αφαιρούμε τις υπάρχουσες μονάδες ως έχουν, το αποτέλεσμα δεν αρέσει πάντα στους προγραμματιστές και η επιχειρηματική διαδικασία μπορεί να έχει καταστεί ξεπερασμένη από τη δημιουργία της λειτουργικότητας. Με το refactoring, μπορούμε να υποστηρίξουμε μια νέα επιχειρηματική διαδικασία, επειδή οι επιχειρηματικές απαιτήσεις αλλάζουν συνεχώς. Μπορούμε να βελτιώσουμε τον πηγαίο κώδικα, να αφαιρέσουμε γνωστά ελαττώματα και να δημιουργήσουμε ένα καλύτερο μοντέλο δεδομένων. Υπάρχουν πολλά οφέλη που προκύπτουν.
Ο διαχωρισμός των υπηρεσιών από την επεξεργασία είναι άρρηκτα συνδεδεμένος με την έννοια του περιορισμένου πλαισίου. Αυτή είναι μια ιδέα από το Domain Driven Design. Σημαίνει ένα τμήμα του μοντέλου τομέα στο οποίο όλοι οι όροι μιας γλώσσας ορίζονται μοναδικά. Ας δούμε το πλαίσιο της ασφάλισης και των λογαριασμών ως παράδειγμα. Έχουμε μια μονολιθική εφαρμογή και πρέπει να δουλέψουμε με τον λογαριασμό στην ασφάλιση. Αναμένουμε από τον προγραμματιστή να βρει μια υπάρχουσα κατηγορία Λογαριασμού σε άλλη συναρμολόγηση, να την παραπέμψει από την κατηγορία Ασφάλιση και θα έχουμε κώδικα εργασίας. Η αρχή DRY θα τηρηθεί, η εργασία θα γίνει πιο γρήγορα χρησιμοποιώντας τον υπάρχοντα κώδικα.
Ως αποτέλεσμα, αποδεικνύεται ότι τα πλαίσια λογαριασμών και ασφάλισης συνδέονται. Καθώς εμφανίζονται νέες απαιτήσεις, αυτή η σύζευξη θα παρεμποδίσει την ανάπτυξη, αυξάνοντας την πολυπλοκότητα της ήδη πολύπλοκης επιχειρηματικής λογικής. Για να λύσετε αυτό το πρόβλημα, πρέπει να βρείτε τα όρια μεταξύ των πλαισίων στον κώδικα και να καταργήσετε τις παραβιάσεις τους. Για παράδειγμα, στο ασφαλιστικό πλαίσιο, είναι πολύ πιθανό να επαρκούν ένας 20ψήφιος αριθμός λογαριασμού Κεντρικής Τράπεζας και η ημερομηνία ανοίγματος του λογαριασμού.
Για να διαχωρίσουμε αυτά τα οριοθετημένα περιβάλλοντα μεταξύ τους και να ξεκινήσουμε τη διαδικασία διαχωρισμού των μικροϋπηρεσιών από μια μονολιθική λύση, χρησιμοποιήσαμε μια προσέγγιση όπως η δημιουργία εξωτερικών API εντός της εφαρμογής. Εάν γνωρίζαμε ότι κάποια μονάδα θα έπρεπε να γίνει microservice, με κάποιο τρόπο τροποποιημένη εντός της διαδικασίας, τότε κάναμε αμέσως κλήσεις στη λογική που ανήκει σε ένα άλλο περιορισμένο πλαίσιο μέσω εξωτερικών κλήσεων. Για παράδειγμα, μέσω REST ή WCF.
Αποφασίσαμε αποφασιστικά ότι δεν θα αποφύγουμε τον κωδικό που θα απαιτούσε κατανεμημένες συναλλαγές. Στην περίπτωσή μας, αποδείχθηκε ότι ήταν αρκετά εύκολο να ακολουθήσουμε αυτόν τον κανόνα. Δεν έχουμε ακόμη αντιμετωπίσει καταστάσεις όπου απαιτούνται πραγματικά αυστηρές κατανεμημένες συναλλαγές - η τελική συνέπεια μεταξύ των μονάδων είναι αρκετά επαρκής.
Ας δούμε ένα συγκεκριμένο παράδειγμα. Έχουμε την έννοια του ενορχηστρωτή - ενός αγωγού που επεξεργάζεται την οντότητα της «εφαρμογής». Δημιουργεί έναν πελάτη, έναν λογαριασμό και μια τραπεζική κάρτα με τη σειρά του. Εάν ο πελάτης και ο λογαριασμός δημιουργηθούν με επιτυχία, αλλά η δημιουργία της κάρτας αποτύχει, η εφαρμογή δεν μεταβαίνει στην κατάσταση "επιτυχής" και παραμένει στην κατάσταση "η κάρτα δεν δημιουργήθηκε". Στο μέλλον, η δραστηριότητα παρασκηνίου θα το πάρει και θα το ολοκληρώσει. Το σύστημα βρίσκεται σε κατάσταση ασυνέπειας εδώ και αρκετό καιρό, αλλά είμαστε γενικά ικανοποιημένοι με αυτό.
Εάν προκύψει μια κατάσταση όταν είναι απαραίτητο να αποθηκεύσετε με συνέπεια μέρος των δεδομένων, πιθανότατα θα πάμε για ενοποίηση της υπηρεσίας προκειμένου να την επεξεργαστούμε σε μία διαδικασία.
Ας δούμε ένα παράδειγμα εκχώρησης μιας μικρουπηρεσίας. Πώς μπορείτε να το φέρετε στην παραγωγή σχετικά με ασφάλεια; Σε αυτό το παράδειγμα, έχουμε ένα ξεχωριστό τμήμα του συστήματος - μια ενότητα υπηρεσίας μισθοδοσίας, μία από τις ενότητες κωδικών της οποίας θα θέλαμε να δημιουργήσουμε microservice.

Πρώτα απ 'όλα, δημιουργούμε μια microservice ξαναγράφοντας τον κώδικα. Βελτιώνουμε ορισμένες πτυχές με τις οποίες δεν ήμασταν ευχαριστημένοι. Εφαρμόζουμε νέες επιχειρηματικές απαιτήσεις από τον πελάτη. Προσθέτουμε μια πύλη API στη σύνδεση μεταξύ του UI και του backend, το οποίο θα παρέχει προώθηση κλήσεων.

Στη συνέχεια, αφήνουμε αυτή τη διαμόρφωση σε λειτουργία, αλλά σε πιλοτική κατάσταση. Οι περισσότεροι από τους χρήστες μας εξακολουθούν να εργάζονται με παλιές επιχειρηματικές διαδικασίες. Για νέους χρήστες, αναπτύσσουμε μια νέα έκδοση της μονολιθικής εφαρμογής που δεν περιέχει πλέον αυτή τη διαδικασία. Ουσιαστικά, έχουμε έναν συνδυασμό μονόλιθου και microservice που λειτουργεί ως πιλότος.

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

Συνολικά, χρησιμοποιούμε σχεδόν όλες τις υπάρχουσες μεθόδους για τον διαχωρισμό του πηγαίου κώδικα ενός μονόλιθου. Όλα μας επιτρέπουν να μειώσουμε το μέγεθος των τμημάτων της εφαρμογής και να τα μεταφράσουμε σε νέες βιβλιοθήκες, δημιουργώντας καλύτερο πηγαίο κώδικα.
Εργασία με τη βάση δεδομένων
Η βάση δεδομένων μπορεί να χωριστεί χειρότερα από τον πηγαίο κώδικα, καθώς περιέχει όχι μόνο το τρέχον σχήμα, αλλά και συσσωρευμένα ιστορικά δεδομένα.
Η βάση δεδομένων μας, όπως και πολλές άλλες, είχε ένα άλλο σημαντικό μειονέκτημα - το τεράστιο μέγεθός της. Αυτή η βάση δεδομένων σχεδιάστηκε σύμφωνα με την περίπλοκη επιχειρηματική λογική ενός μονόλιθου και συσσωρεύονται σχέσεις μεταξύ των πινάκων διαφόρων οριοθετημένων πλαισίων.
Στην περίπτωσή μας, για να ξεπεράσουμε όλα τα προβλήματα (μεγάλη βάση δεδομένων, πολλές συνδέσεις, μερικές φορές ασαφή όρια μεταξύ πινάκων), προέκυψε ένα πρόβλημα που παρουσιάζεται σε πολλά μεγάλα έργα: η χρήση του προτύπου κοινής βάσης δεδομένων. Τα δεδομένα ελήφθησαν από πίνακες μέσω προβολής, μέσω αναπαραγωγής και αποστέλλονταν σε άλλα συστήματα όπου χρειαζόταν αυτή η αναπαραγωγή. Ως αποτέλεσμα, δεν μπορέσαμε να μετακινήσουμε τους πίνακες σε ξεχωριστό σχήμα επειδή χρησιμοποιήθηκαν ενεργά.
Η ίδια διαίρεση σε περιορισμένα πλαίσια στον κώδικα μας βοηθάει στον διαχωρισμό. Συνήθως μας δίνει μια πολύ καλή ιδέα για το πώς αναλύουμε τα δεδομένα σε επίπεδο βάσης δεδομένων. Καταλαβαίνουμε ποιοι πίνακες ανήκουν σε ένα περιορισμένο περιβάλλον και ποιοι σε ένα άλλο.
Χρησιμοποιήσαμε δύο καθολικές μεθόδους κατάτμησης βάσεων δεδομένων: κατάτμηση υπαρχόντων πινάκων και κατάτμηση με επεξεργασία.
Ο διαχωρισμός των υπαρχόντων πινάκων είναι μια καλή μέθοδος για χρήση εάν η δομή δεδομένων είναι καλή, πληροί τις επιχειρηματικές απαιτήσεις και όλοι είναι ευχαριστημένοι με αυτό. Σε αυτήν την περίπτωση, μπορούμε να διαχωρίσουμε τους υπάρχοντες πίνακες σε ένα ξεχωριστό σχήμα.
Ένα τμήμα με επεξεργασία χρειάζεται όταν το επιχειρηματικό μοντέλο έχει αλλάξει πολύ, και οι πίνακες δεν μας ικανοποιούν πλέον καθόλου.
Διαίρεση υπαρχόντων πινάκων. Πρέπει να καθορίσουμε τι θα χωρίσουμε. Χωρίς αυτή τη γνώση, τίποτα δεν θα λειτουργήσει, και εδώ ο διαχωρισμός των οριοθετημένων πλαισίων στον κώδικα θα μας βοηθήσει. Κατά κανόνα, εάν μπορείτε να κατανοήσετε τα όρια των πλαισίων στον πηγαίο κώδικα, γίνεται σαφές ποιοι πίνακες πρέπει να περιλαμβάνονται στη λίστα για το τμήμα.
Ας φανταστούμε ότι έχουμε μια λύση στην οποία δύο μονολιθικές μονάδες αλληλεπιδρούν με μια βάση δεδομένων. Πρέπει να βεβαιωθούμε ότι μόνο μια λειτουργική μονάδα αλληλεπιδρά με την ενότητα των χωριστών πινάκων και η άλλη αρχίζει να αλληλεπιδρά μαζί της μέσω του API. Αρχικά, αρκεί να πραγματοποιείται μόνο η εγγραφή μέσω του API. Αυτή είναι απαραίτητη προϋπόθεση για να μιλήσουμε για την ανεξαρτησία των μικροϋπηρεσιών. Οι συνδέσεις ανάγνωσης μπορούν να παραμείνουν όσο δεν υπάρχει μεγάλο πρόβλημα.

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

Αργότερα θα καταργήσουμε αυτήν τη σύνδεση, δηλαδή, η ανάγνωση δεδομένων από μια μονολιθική εφαρμογή από χωριστούς πίνακες θα μεταφερθεί επίσης στο API.

Στη συνέχεια, θα επιλέξουμε από τη γενική βάση δεδομένων τους πίνακες με τους οποίους λειτουργεί μόνο η νέα microservice. Μπορούμε να μετακινήσουμε τους πίνακες σε ξεχωριστό σχήμα ή ακόμα και σε ξεχωριστή φυσική βάση δεδομένων. Υπάρχει ακόμα μια σύνδεση ανάγνωσης μεταξύ της microservice και της monolith βάσης δεδομένων, αλλά δεν υπάρχει τίποτα ανησυχητικό, σε αυτήν τη διαμόρφωση μπορεί να διαρκέσει για πολύ καιρό.

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

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

Για να λειτουργήσει αυτό το σχέδιο, πιθανότατα θα χρειαστούμε μια μεταβατική περίοδο.
Στη συνέχεια, υπάρχουν δύο πιθανές προσεγγίσεις.
Πρώτα: αντιγράφουμε όλα τα δεδομένα στη νέα και την παλιά βάση δεδομένων. Σε αυτήν την περίπτωση, έχουμε πλεονασμό δεδομένων και ενδέχεται να προκύψουν προβλήματα συγχρονισμού. Αλλά μπορούμε να πάρουμε δύο διαφορετικούς πελάτες. Το ένα θα λειτουργεί με τη νέα έκδοση, το άλλο με την παλιά.
Δεύτερος: χωρίζουμε τα δεδομένα σύμφωνα με ορισμένα επιχειρηματικά κριτήρια. Για παράδειγμα, είχαμε 5 προϊόντα στο σύστημα που ήταν αποθηκευμένα στην παλιά βάση δεδομένων. Τοποθετούμε το έκτο στο πλαίσιο της νέας επιχειρηματικής εργασίας σε μια νέα βάση δεδομένων. Αλλά θα χρειαστούμε μια πύλη API που θα συγχρονίζει αυτά τα δεδομένα και θα δείχνει στον πελάτη από πού και από τι να πάρει.
Και οι δύο προσεγγίσεις λειτουργούν, επιλέξτε ανάλογα με την κατάσταση.
Αφού βεβαιωθούμε ότι όλα λειτουργούν, το τμήμα του μονόλιθου που λειτουργεί με παλιές δομές βάσης δεδομένων μπορεί να απενεργοποιηθεί.

Το τελευταίο βήμα είναι να αφαιρέσετε τις παλιές δομές δεδομένων.

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

Μπορεί να χωριστεί χονδρικά σε τρία στρώματα. Αυτό είναι ένα στρώμα από λειτουργικές ενότητες, προσθήκες, υπηρεσίες και μεμονωμένες δραστηριότητες. Στην πραγματικότητα, αυτά ήταν σημεία εισόδου σε μια μονολιθική λύση. Όλα σφραγίστηκαν καλά με ένα κοινό στρώμα. Είχε επιχειρηματική λογική που μοιραζόταν μεταξύ υπηρεσιών και πολλών συνδέσεων. Κάθε υπηρεσία και πρόσθετο χρησιμοποιούσε έως και 10 ή περισσότερες κοινές συναρμολογήσεις, ανάλογα με το μέγεθός τους και τη συνείδηση των προγραμματιστών.
Ήμασταν τυχεροί που είχαμε βιβλιοθήκες υποδομής που θα μπορούσαν να χρησιμοποιηθούν ξεχωριστά.
Μερικές φορές προέκυψε μια κατάσταση όταν ορισμένα κοινά αντικείμενα δεν ανήκαν στην πραγματικότητα σε αυτό το επίπεδο, αλλά ήταν βιβλιοθήκες υποδομής. Αυτό λύθηκε με μετονομασία.
Η μεγαλύτερη ανησυχία ήταν τα περιορισμένα πλαίσια. Συνέβη 3-4 περιβάλλοντα να αναμειγνύονται σε μια κοινή συνέλευση και να χρησιμοποιούν το ένα το άλλο στις ίδιες επιχειρηματικές λειτουργίες. Ήταν απαραίτητο να κατανοήσουμε πού θα μπορούσε να χωριστεί αυτό και σε ποια όρια, και τι να κάνουμε στη συνέχεια με την αντιστοίχιση αυτής της διαίρεσης σε συγκροτήματα πηγαίου κώδικα.
Έχουμε διαμορφώσει αρκετούς κανόνες για τη διαδικασία διαχωρισμού κώδικα.
Η πρώτη: Δεν θέλαμε πλέον να μοιραζόμαστε την επιχειρηματική λογική μεταξύ υπηρεσιών, δραστηριοτήτων και προσθηκών. Θέλαμε να κάνουμε την επιχειρηματική λογική ανεξάρτητη στο πλαίσιο των microservices. Οι μικροϋπηρεσίες, από την άλλη πλευρά, θεωρούνται ιδανικά ως υπηρεσίες που υπάρχουν εντελώς ανεξάρτητα. Πιστεύω ότι αυτή η προσέγγιση είναι κάπως σπάταλη και είναι δύσκολο να επιτευχθεί, γιατί, για παράδειγμα, οι υπηρεσίες σε C# θα συνδέονται σε κάθε περίπτωση με μια τυπική βιβλιοθήκη. Το σύστημά μας είναι γραμμένο σε C#, δεν έχουμε χρησιμοποιήσει ακόμη άλλες τεχνολογίες. Ως εκ τούτου, αποφασίσαμε ότι είχαμε την οικονομική δυνατότητα να χρησιμοποιήσουμε κοινές τεχνικές συναρμολογήσεις. Το κυριότερο είναι ότι δεν περιέχουν θραύσματα επιχειρηματικής λογικής. Εάν έχετε ένα βολικό περιτύλιγμα πάνω από το ORM που χρησιμοποιείτε, τότε η αντιγραφή του από υπηρεσία σε υπηρεσία είναι πολύ ακριβή.
Η ομάδα μας είναι λάτρης της σχεδίασης που βασίζεται στον τομέα, επομένως η αρχιτεκτονική κρεμμυδιού ήταν πολύ καλή για εμάς. Η βάση των υπηρεσιών μας δεν είναι το επίπεδο πρόσβασης δεδομένων, αλλά ένα συγκρότημα με λογική τομέα, το οποίο περιέχει μόνο επιχειρηματική λογική και δεν έχει συνδέσεις με την υποδομή. Ταυτόχρονα, μπορούμε να τροποποιήσουμε ανεξάρτητα τη συγκρότηση τομέα για την επίλυση προβλημάτων που σχετίζονται με πλαίσια.
Σε αυτό το στάδιο αντιμετωπίσαμε το πρώτο μας σοβαρό πρόβλημα. Η υπηρεσία έπρεπε να αναφέρεται σε ένα συγκρότημα τομέα, θέλαμε να κάνουμε τη λογική ανεξάρτητη και η αρχή DRY μας εμπόδισε πολύ εδώ. Οι προγραμματιστές ήθελαν να επαναχρησιμοποιήσουν κλάσεις από γειτονικές συναρμολογήσεις για να αποφύγουν την αντιγραφή, και ως αποτέλεσμα, οι τομείς άρχισαν να συνδέονται ξανά μεταξύ τους. Αναλύσαμε τα αποτελέσματα και αποφασίσαμε ότι ίσως το πρόβλημα βρίσκεται και στην περιοχή της συσκευής αποθήκευσης πηγαίου κώδικα. Είχαμε ένα μεγάλο αποθετήριο που περιείχε όλο τον πηγαίο κώδικα. Η λύση για ολόκληρο το έργο ήταν πολύ δύσκολο να συναρμολογηθεί σε μια τοπική μηχανή. Ως εκ τούτου, δημιουργήθηκαν ξεχωριστές μικρές λύσεις για μέρη του έργου και κανείς δεν απαγόρευσε την προσθήκη κάποιας κοινής διάταξης ή συναρμολόγησης τομέα σε αυτές και την επαναχρησιμοποίησή τους. Το μόνο εργαλείο που δεν μας επέτρεψε να το κάνουμε αυτό ήταν ο έλεγχος κώδικα. Μερικές φορές όμως απέτυχε επίσης.
Μετά αρχίσαμε να κινούμαστε σε ένα μοντέλο με ξεχωριστά αποθετήρια. Η επιχειρηματική λογική δεν ρέει πλέον από υπηρεσία σε υπηρεσία, οι τομείς έχουν γίνει πραγματικά ανεξάρτητοι. Τα οριοθετημένα περιβάλλοντα υποστηρίζονται με μεγαλύτερη σαφήνεια. Πώς επαναχρησιμοποιούμε τις βιβλιοθήκες υποδομής; Τα χωρίσαμε σε ξεχωριστό αποθετήριο και μετά τα τοποθετήσαμε σε πακέτα Nuget, τα οποία βάλαμε στο Artifactory. Με οποιαδήποτε αλλαγή, η συναρμολόγηση και η δημοσίευση γίνονται αυτόματα.

Οι υπηρεσίες μας άρχισαν να αναφέρονται σε εσωτερικά πακέτα υποδομής με τον ίδιο τρόπο όπως και σε εξωτερικά. Κατεβάζουμε εξωτερικές βιβλιοθήκες από το Nuget. Για να δουλέψουμε με το Artifactory, όπου τοποθετήσαμε αυτά τα πακέτα, χρησιμοποιήσαμε δύο διαχειριστές πακέτων. Σε μικρά αποθετήρια χρησιμοποιούσαμε επίσης Nuget. Σε αποθετήρια με πολλαπλές υπηρεσίες, χρησιμοποιήσαμε το Paket, το οποίο παρέχει μεγαλύτερη συνέπεια στην έκδοση μεταξύ των λειτουργικών μονάδων.

Έτσι, δουλεύοντας στον πηγαίο κώδικα, αλλάζοντας ελαφρώς την αρχιτεκτονική και διαχωρίζοντας τα αποθετήρια, κάνουμε τις υπηρεσίες μας πιο ανεξάρτητες.
Προβλήματα υποδομής
Τα περισσότερα από τα μειονεκτήματα της μετάβασης σε μικροϋπηρεσίες σχετίζονται με τις υποδομές. Θα χρειαστείτε αυτοματοποιημένη ανάπτυξη, θα χρειαστείτε νέες βιβλιοθήκες για την εκτέλεση της υποδομής.
Χειροκίνητη εγκατάσταση σε περιβάλλοντα
Αρχικά, εγκαταστήσαμε χειροκίνητα τη λύση για περιβάλλοντα. Για να αυτοματοποιήσουμε αυτή τη διαδικασία, δημιουργήσαμε μια διοχέτευση CI/CD. Επιλέξαμε τη διαδικασία συνεχούς παράδοσης επειδή η συνεχής ανάπτυξη δεν είναι ακόμη αποδεκτή για εμάς από την άποψη των επιχειρηματικών διαδικασιών. Επομένως, η αποστολή για λειτουργία πραγματοποιείται χρησιμοποιώντας ένα κουμπί και για δοκιμή - αυτόματα.

Χρησιμοποιούμε Atlassian, Bitbucket για αποθήκευση πηγαίου κώδικα και Bamboo για δόμηση. Μας αρέσει να γράφουμε σενάρια κατασκευής στο Cake γιατί είναι το ίδιο με το C#. Τα έτοιμα πακέτα έρχονται στο Artifactory και το Ansible φτάνει αυτόματα στους δοκιμαστικούς διακομιστές, μετά τον οποίο μπορούν να δοκιμαστούν αμέσως.

Ξεχωριστή υλοτομία
Κάποτε, μία από τις ιδέες του μονόλιθου ήταν να παρέχει κοινόχρηστη υλοτομία. Χρειαζόμασταν επίσης να καταλάβουμε τι να κάνουμε με τα μεμονωμένα αρχεία καταγραφής που βρίσκονται στους δίσκους. Τα αρχεία καταγραφής μας είναι γραμμένα σε αρχεία κειμένου. Αποφασίσαμε να χρησιμοποιήσουμε μια τυπική στοίβα ELK. Δεν γράψαμε στον ELK απευθείας μέσω των παρόχων, αλλά αποφασίσαμε να οριστικοποιήσουμε τα αρχεία καταγραφής κειμένου και να γράψουμε το αναγνωριστικό ίχνους σε αυτά ως αναγνωριστικό, προσθέτοντας το όνομα της υπηρεσίας, ώστε αυτά τα αρχεία καταγραφής να αναλυθούν αργότερα.

Με το Filebeat μπορούμε να συλλέξουμε τα αρχεία καταγραφής μας από διακομιστές, στη συνέχεια, μετασχηματίστε τα, χρησιμοποιήστε το Kibana για να δημιουργήσετε ερωτήματα στο περιβάλλον χρήστη και δείτε πώς δρομολογήθηκε η κλήση μεταξύ των υπηρεσιών. Τα αναγνωριστικά παρακολούθησης είναι πολύ χρήσιμα για αυτό.
Δοκιμή και εντοπισμός σφαλμάτων σχετικών υπηρεσιών
Αρχικά, δεν καταλάβαμε πλήρως τον τρόπο εντοπισμού σφαλμάτων των υπηρεσιών που αναπτύσσονται. Όλα ήταν απλά με το μονόλιθο. Στην αρχή προσπάθησαν να κάνουν το ίδιο με τις microservices, αλλά μερικές φορές για να εκκινήσετε πλήρως μια microservice πρέπει να ξεκινήσετε πολλές άλλες, και αυτό είναι άβολο. Συνειδητοποιήσαμε ότι πρέπει να μεταβούμε σε ένα μοντέλο όπου αφήνουμε στον τοπικό υπολογιστή μόνο την υπηρεσία ή τις υπηρεσίες που θέλουμε να εντοπίσουμε σφάλματα. Οι υπόλοιπες υπηρεσίες χρησιμοποιούνται από διακομιστές που ταιριάζουν στη διαμόρφωση με το prod. Μετά την αποσφαλμάτωση, κατά τη διάρκεια της δοκιμής, για κάθε εργασία, μόνο οι αλλαγμένες υπηρεσίες εκδίδονται στον δοκιμαστικό διακομιστή. Έτσι, το διάλυμα δοκιμάζεται με τη μορφή με την οποία θα εμφανιστεί στην παραγωγή στο μέλλον.
Υπάρχουν διακομιστές που εκτελούν μόνο εκδόσεις παραγωγής υπηρεσιών. Αυτοί οι διακομιστές χρειάζονται σε περίπτωση συμβάντων, για έλεγχο παράδοσης πριν από την ανάπτυξη και για εσωτερική εκπαίδευση.
Προσθέσαμε μια αυτοματοποιημένη διαδικασία δοκιμών χρησιμοποιώντας τη δημοφιλή βιβλιοθήκη Specflow. Οι δοκιμές εκτελούνται αυτόματα χρησιμοποιώντας το NUnit αμέσως μετά την ανάπτυξη από το Ansible. Εάν η κάλυψη εργασιών είναι πλήρως αυτόματη, τότε δεν χρειάζεται χειροκίνητη δοκιμή. Παρόλο που μερικές φορές απαιτείται επιπλέον χειροκίνητος έλεγχος. Χρησιμοποιούμε ετικέτες στο Jira για να καθορίσουμε ποιες δοκιμές θα εκτελεστούν για ένα συγκεκριμένο ζήτημα.
Επιπλέον, η ανάγκη για δοκιμή φορτίου έχει αυξηθεί. Χρησιμοποιούμε το JMeter για την εκτέλεση δοκιμών, το InfluxDB για την αποθήκευση τους και το Grafana για τη δημιουργία γραφημάτων διεργασιών.
Τι έχουμε πετύχει;
Πρώτον, απαλλαγήκαμε από την έννοια της "απελευθέρωσης". Πέρασαν οι δίμηνες τερατώδεις εκδόσεις όταν αυτός ο κολοσσός αναπτύχθηκε σε περιβάλλον παραγωγής, διακόπτοντας προσωρινά τις επιχειρηματικές διαδικασίες. Τώρα αναπτύσσουμε υπηρεσίες κατά μέσο όρο κάθε 1,5 ημέρα, ομαδοποιώντας τις επειδή τίθενται σε λειτουργία μετά την έγκριση.
Δεν υπάρχουν μοιραίες βλάβες στο σύστημά μας. Εάν κυκλοφορήσουμε μια microservice με σφάλμα, τότε η λειτουργικότητα που σχετίζεται με αυτήν θα σπάσει και δεν θα επηρεαστεί όλες οι άλλες λειτουργίες. Αυτό βελτιώνει σημαντικά την εμπειρία χρήστη.
Μπορούμε να ελέγξουμε το μοτίβο ανάπτυξης. Μπορείτε να επιλέξετε ομάδες υπηρεσιών ξεχωριστά από την υπόλοιπη λύση, εάν είναι απαραίτητο.
Επιπλέον, μειώσαμε σημαντικά το πρόβλημα με μια μεγάλη ουρά βελτιώσεων. Τώρα έχουμε ξεχωριστές ομάδες προϊόντων που συνεργάζονται με ορισμένες από τις υπηρεσίες ανεξάρτητα. Η διαδικασία Scrum ταιριάζει ήδη εδώ. Μια συγκεκριμένη ομάδα μπορεί να έχει έναν ξεχωριστό Κάτοχο Προϊόντος που της αναθέτει εργασίες.
Περίληψη
- Οι μικροϋπηρεσίες είναι κατάλληλες για την αποσύνθεση πολύπλοκων συστημάτων. Στην πορεία, αρχίζουμε να καταλαβαίνουμε τι υπάρχει στο σύστημά μας, ποια περιορισμένα πλαίσια υπάρχουν, πού βρίσκονται τα όριά τους. Αυτό σας επιτρέπει να κατανέμετε σωστά τις βελτιώσεις μεταξύ των λειτουργικών μονάδων και να αποτρέπετε τη σύγχυση του κώδικα.
- Οι μικροϋπηρεσίες παρέχουν οργανωτικά οφέλη. Συχνά αναφέρονται μόνο ως αρχιτεκτονική, αλλά οποιαδήποτε αρχιτεκτονική χρειάζεται για να λύσει τις επιχειρηματικές ανάγκες και όχι από μόνη της. Επομένως, μπορούμε να πούμε ότι οι μικροϋπηρεσίες είναι κατάλληλες για την επίλυση προβλημάτων σε μικρές ομάδες, δεδομένου ότι το Scrum είναι πολύ δημοφιλές τώρα.
- Ο διαχωρισμός είναι μια επαναληπτική διαδικασία. Δεν μπορείς να πάρεις μια εφαρμογή και απλά να τη χωρίσεις σε μικροϋπηρεσίες. Το προϊόν που προκύπτει είναι απίθανο να είναι λειτουργικό. Όταν αφιερώνουμε μικροϋπηρεσίες, είναι ωφέλιμο να ξαναγράψουμε την υπάρχουσα κληρονομιά, δηλαδή να τη μετατρέψουμε σε κώδικα που μας αρέσει και ανταποκρίνεται καλύτερα στις επιχειρηματικές ανάγκες όσον αφορά τη λειτουργικότητα και την ταχύτητα.
Μια μικρή προειδοποίηση: Το κόστος μετάβασης σε μικροϋπηρεσίες είναι αρκετά σημαντικό. Χρειάστηκε πολύς χρόνος για να λυθεί μόνο το πρόβλημα των υποδομών. Επομένως, εάν έχετε μια μικρή εφαρμογή που δεν απαιτεί συγκεκριμένη κλιμάκωση, εκτός αν έχετε μεγάλο αριθμό πελατών που ανταγωνίζονται για την προσοχή και τον χρόνο της ομάδας σας, τότε οι μικροϋπηρεσίες μπορεί να μην είναι αυτό που χρειάζεστε σήμερα. Είναι αρκετά ακριβό. Εάν ξεκινήσετε τη διαδικασία με μικροϋπηρεσίες, τότε το κόστος θα είναι αρχικά υψηλότερο από ό,τι αν ξεκινήσετε το ίδιο έργο με την ανάπτυξη ενός μονόλιθου.
ΥΓ Μια πιο συναισθηματική ιστορία (και σαν για εσάς προσωπικά) - σύμφωνα με .
Ακολουθεί η πλήρης έκδοση της έκθεσης.
Πηγή: www.habr.com
