Ιστολόγιο

Ξύπνημα βάσεων δεδομένων χωρίς νεκρές συνδέσεις

Οι δημοσιευμένες εφαρμογές του Mythex, και οι βάσεις τους, κοιμούνται όταν δεν τις χρησιμοποιεί κανείς. Όταν μια εφαρμογή ξυπνούσε, μπορούσε να κρατά το πρώτο αίτημα 10–12 δευτερόλεπτα, επειδή προσπαθούσε να επαναχρησιμοποιήσει συνδέσεις βάσης δεδομένων που είχαν πεθάνει όσο όλα κοιμόντουσαν. Τώρα δίνουμε στις εφαρμογές Spring Boot ρυθμίσεις βάσης δεδομένων που αντέχουν τον ύπνο, και λέμε στον πράκτορα να χτίζει εφαρμογές οποιασδήποτε στοίβας με τον ίδιο τρόπο. Στην πλατφόρμα φιλοξενίας, το πρώτο αίτημα μετά από ξύπνημα πήγε από 12,7 δευτερόλεπτα σε 2,3 δευτερόλεπτα.

Γιατί κοιμούνται εφαρμογές και βάσεις

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

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

Το σύμπτωμα: μια αργή πρώτη επίσκεψη

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

Τι συμβαίνει με τον ύπνο:

  1. Η εφαρμογή τρέχει, με λίγες αδρανείς συνδέσεις στο pool της.
  2. Κανείς δεν την επισκέπτεται. Το μηχάνημα της εφαρμογής αναστέλλεται — παγωμένο, με το pool του άθικτο.
  3. Η βάση κοιμάται και αφήνει κάτω το δικό της άκρο κάθε σύνδεσης.
  4. Φτάνει ένας επισκέπτης. Η εφαρμογή ξυπνά ακριβώς όπως ήταν, κρατώντας ακόμη συνδέσεις που η βάση δεν γνωρίζει πια.
  5. Το pool δίνει μία από αυτές τις συνδέσεις. Πρέπει να μάθει ότι είναι νεκρή — δοκιμάζοντάς τη και περιμένοντας — πριν τη βγάλει εκτός.

Σε μια εφαρμογή Spring Boot, η επικύρωση εκείνων των νεκρών συνδέσεων μπλόκαρε το πρώτο αίτημα για περίπου 10 δευτερόλεπτα πριν αποτύχει με «Connection is not available». Για τον επισκέπτη, ο ιστότοπος απλώς κρεμούσε, και μετά ίσως έδειχνε σφάλμα.

Γιατί οι εφαρμογές Spring έπαθαν το χειρότερο

Το Spring Boot είναι δημοφιλές framework της Java, και χρησιμοποιεί από προεπιλογή ένα pool συνδέσεων που λέγεται HikariCP. Το Spring μπορεί να ρυθμίσει το pool από ρυθμίσεις, συμπεριλαμβανομένου του πόσες αδρανείς συνδέσεις να κρατά.

Όμως το Mythex δίνει σε κάθε εφαρμογή τη βάση της ως ένα μόνο DATABASE_URL με μορφή postgresql://user:pass@host/db. Το Spring δεν μπορεί να διαβάσει άμεσα αυτή τη μορφή. Οπότε οι εφαρμογές Spring που χτίζονταν στο Mythex δημιουργούσαν μόνες τους το pool στον κώδικα, αναλύοντας αυτό το URL — και ένα pool φτιαγμένο με το χέρι αγνοεί όλες τις ρυθμίσεις spring.datasource.*. Ακόμη κι αν κάποιος ήξερε τις σωστές ρυθμίσεις pool, δεν υπήρχε πουθενά να εφαρμοστούν.

Η διόρθωση, μέρος 1: ρυθμίσεις που μπορεί να χρησιμοποιήσει το Spring

Όταν ένα έργο έχει βάση δεδομένων, του δίνουμε πλέον και μεταβλητές περιβάλλοντος που το Spring διαβάζει εγγενώς:

  • SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME και SPRING_DATASOURCE_PASSWORD, μετατρεπόμενα από το DATABASE_URL (με απαίτηση SSL εκτός αν το URL λέει διαφορετικά).
  • Ρυθμίσεις pool που επιβιώνουν τον ύπνο:
ΡύθμισηΤιμήΓιατί
Ελάχιστες αδρανείς συνδέσεις0Να μην μένει τίποτα ανοιχτό ανάμεσα στα αιτήματα, ώστε να μην υπάρχει τι να παλιώσει
Χρονικό όριο αδράνειας30 δευτερόλεπταΚλείνει σύντομα τις αχρησιμοποίητες συνδέσεις
Μέγιστη διάρκεια ζωής2 λεπτάΑποσύρει κάθε σύνδεση πριν μπορέσει να γεράσει
Χρονικό όριο σύνδεσης5 δευτερόλεπταΝα μην κρατά πολύ ένα αίτημα αν η βάση αργεί να απαντήσει

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

Όταν αυτές οι μεταβλητές υπάρχουν, το Spring ρυθμίζει το ίδιο το pool, και οι ρυθμίσεις ισχύουν. Ό,τι έχει ορίσει μόνο του το έργο υπερισχύει πάντα· εμείς συμπληρώνουμε μόνο ό,τι λείπει. Οι εφαρμογές που δεν είναι Spring αγνοούν αυτές τις μεταβλητές.

Η λεπτομέρεια που παραλίγο να μην κάνει τίποτα

Το Spring αντιστοιχίζει μεταβλητές περιβάλλοντος στις ρυθμίσεις του με έναν κανόνα που είναι εύκολο να γίνει λάθος. Η ρύθμιση minimum-idle πρέπει να γράφεται ως SPRING_DATASOURCE_HIKARI_MINIMUMIDLE — παύλες αφαιρεμένες, λέξεις ενωμένες. Αν γραφτεί ως SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE, που φαίνεται πιο φυσικό, αντιστοιχίζεται σε διαφορετική, ανύπαρκτη ρύθμιση (minimum.idle) και αγνοείται αθόρυβα.

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

Η διόρθωση, μέρος 2: κάθε άλλη στοίβα

Το Spring δεν είναι το μόνο framework με pool, και δεν μπορούμε να προρυθμίσουμε κάθε βιβλιοθήκη σε κάθε γλώσσα. Γι' αυτό ο πράκτορας του Mythex — η τεχνητή νοημοσύνη που γράφει την εφαρμογή σας — έχει πλέον μόνιμη οδηγία για οποιαδήποτε στοίβα: οι δημοσιευμένες εφαρμογές και οι βάσεις τους κοιμούνται όταν είναι αδρανείς, άρα μια σύνδεση που κρατιέται ανοιχτή μπορεί να είναι νεκρή στο επόμενο αίτημα. Πρέπει να:

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

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

Το αποτέλεσμα

Μετρημένο στην πλατφόρμα φιλοξενίας στην οποία τρέχουμε δημοσιευμένες εφαρμογές, το πρώτο αίτημα μετά από ξύπνημα πήγε από 12,7 δευτερόλεπτα σε 2,3 δευτερόλεπτα.

Τι κρατήσαμε από όλο αυτό

  • Κάθε επίπεδο που κοιμάται πρέπει να συμφωνεί σε τι επιβιώνει. Μια παγωμένη εφαρμογή και μια κοιμισμένη βάση έκαναν η καθεμία εύλογη επιλογή. Μαζί, η εφαρμογή ξύπνησε κρατώντας κατάσταση που δεν ίσχυε πια.
  • Οι προεπιλογές φτιαγμένες για διακομιστές πάντα ενεργούς δεν ταιριάζουν σε εφαρμογές που κλιμακώνονται στο μηδέν. Το να κρατάτε ζεστές συνδέσεις είναι καλή ιδέα μέχρι να κρυώσουν όλα γύρω τους.
  • Δώστε στα frameworks τα δεδομένα τους στη δική τους μορφή. Ένα URL ήταν απλό για εμάς και ανάγκαζε κάθε εφαρμογή Spring να φτιάχνει με το χέρι ένα pool που αγνοούσε τη δική της διαμόρφωση.
  • Ελέγξτε ότι μια ρύθμιση γράφεται όπως την διαβάζει το framework. Μια σωστή τιμή με λάθος όνομα δεν κάνει τίποτα, αθόρυβα.

Αν είστε καινούργιοι στο πώς δουλεύουν οι βάσεις στο Mythex, δείτε την τεκμηρίωση βάσεων δεδομένων και τον οδηγό μας για τι είναι το Postgres.

Mythex · Pricing · Χτίστε οτιδήποτε με AI · Πρότυπα ιστοσελίδων και εφαρμογών · Το Mythex σε σύγκριση · Γλωσσάρι δημιουργίας εφαρμογών με AI · Δωρεάν εργαλεία δημιουργίας εφαρμογών με AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)