Blog

Databases wakker maken zonder dode verbindingen

Gepubliceerde apps op Mythex, en hun databases, gaan slapen wanneer niemand ze gebruikt. Wanneer een app wakker werd, kon hij het eerste verzoek 10 tot 12 seconden vasthouden, omdat hij probeerde databaseverbindingen opnieuw te gebruiken die stierven terwijl alles sliep. We geven Spring Boot-apps nu databaseinstellingen die veilig zijn na een slaapstand, en vertellen de agent om apps met elke stack op dezelfde manier te bouwen. Op het hostingplatform ging het eerste verzoek na een wake-up van 12,7 seconden naar 2,3 seconden.

Waarom apps en databases slapen

Een gepubliceerde Mythex-app draait op een machine die na een paar minuten inactiviteit pauzeert, en de database is serverless Postgres die na vijf minuten inactiviteit slaapt en wakker wordt bij het volgende verzoek. Dat houdt een rustige app goedkoop: je betaalt voor wat de database daadwerkelijk heeft gebruikt, en een slapende app kost niets aan rekenkracht. We schreven over de facturatiekant in databases factureren op basis van wat ze echt gebruiken.

Het addertje is dat de twee apart slapen, en het niet eens zijn over wat een verbinding is.

Het symptoom: een trage eerste bezoek

De meeste serverapps houden een connection pool bij: een handvol open databaseverbindingen die klaarstaan, zodat elk verzoek niet de kosten van het openen van een nieuwe verbinding hoeft te betalen. Dat is het juiste ontwerp voor een app die altijd aan staat.

Dit gebeurt er met een slaapstand:

  1. De app draait, met een paar inactieve verbindingen in zijn pool.
  2. Niemand bezoekt de app. De machine van de app pauzeert, bevroren met zijn pool intact.
  3. De database gaat slapen en laat zijn kant van elke verbinding vallen.
  4. Een bezoeker komt binnen. De app wordt wakker precies zoals hij was, en houdt nog steeds verbindingen vast die de database niet meer kent.
  5. De pool geeft een van die verbindingen uit. Die moet eerst ontdekken dat hij dood is, door het te proberen en te wachten, voordat hij hem opgeeft.

In een Spring Boot-app blokkeerde het valideren van die dode verbindingen het eerste verzoek ongeveer 10 seconden voordat het faalde met „Connection is not available”. Voor de bezoeker hing de site gewoon, en toonde daarna misschien een fout.

Waarom Spring-apps het zwaarst hadden

Spring Boot is een populair Java-framework, en het gebruikt standaard een connection pool genaamd HikariCP. Spring kan die pool configureren via instellingen, inclusief hoeveel inactieve verbindingen er open blijven.

Maar Mythex geeft elke app zijn database als één DATABASE_URL in de vorm postgresql://user:pass@host/db. Spring kan dat formaat niet direct lezen. Dus bouwden Spring-apps op Mythex hun eigen pool in code door die URL te ontleden, en een pool die met de hand is gebouwd negeert alle spring.datasource.*-instellingen van Spring. Zelfs als iemand de juiste poolinstellingen kende, was er geen plek waar ze van kracht werden.

De oplossing, deel 1: instellingen die Spring kan gebruiken

Wanneer een project een database heeft, krijgt het nu ook omgevingsvariabelen die Spring native leest:

  • SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME en SPRING_DATASOURCE_PASSWORD, omgezet uit DATABASE_URL (met SSL verplicht, tenzij de URL iets anders zegt).
  • Poolinstellingen die een slaapstand overleven:
InstellingWaardeWaarom
Minimum aantal inactieve verbindingen0Houd niets open tussen verzoeken, zodat er niets kan verouderen
Idle-timeout30 secondenSluit ongebruikte verbindingen snel
Maximale levensduur2 minutenPensioneer elke verbinding voordat hij oud kan worden
Verbindings-timeout5 secondenHoud een verzoek niet te lang vast als de database traag antwoordt

Omdat er geen inactieve verbindingen worden vastgehouden, opent een wakker geworden app één nieuwe verbinding in plaats van door dode te waden.

Wanneer deze variabelen aanwezig zijn, configureert Spring de pool zelf, en de instellingen gelden. Wat het project zelf heeft ingesteld, wint altijd; wij vullen alleen aan wat ontbreekt. Niet-Spring-apps negeren deze variabelen.

Het detail dat er bijna voor zorgde dat het niets deed

Spring koppelt omgevingsvariabelen aan zijn instellingen volgens een regel die makkelijk verkeerd gaat. De instelling minimum-idle moet worden geschreven als SPRING_DATASOURCE_HIKARI_MINIMUMIDLE: koppeltekens weggelaten, woorden aaneengeschreven. Schrijf je het als SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE, wat natuurlijker lijkt, dan wordt het gekoppeld aan een andere, niet-bestaande instelling (minimum.idle) en wordt het stilletjes genegeerd.

Dat is het soort fout dat elke review doorstaat en in productie niets doet. Dus controleert een test zowel dat de waarden zijn ingesteld als dat geen variabele de vorm met underscores gebruikt.

De oplossing, deel 2: elke andere stack

Spring is niet het enige framework met een pool, en we kunnen niet elke bibliotheek in elke taal vooraf configureren. Dus krijgt de Mythex-agent, de AI die je app schrijft, nu een vaste instructie voor elke stack: gepubliceerde apps en hun databases slapen wanneer ze inactief zijn, dus een verbinding die open wordt gehouden kan bij het volgende verzoek dood zijn. De agent moet:

  • geen inactieve databaseverbindingen open houden, of elke verbinding controleren voor gebruik,
  • één keer opnieuw proberen bij een verbindingsfout, en
  • de databaseinstellingen gebruiken die het platform in de omgeving aanlevert, in plaats van zelf een pool te bouwen door DATABASE_URL te ontleden.

Dat laatste punt sluit de cirkel met deel 1: een app die de aangeleverde instellingen gebruikt, krijgt de slaapveilige configuratie automatisch.

Het resultaat

Gemeten op het hostingplatform waarop we gepubliceerde apps draaien, ging het eerste verzoek na een wake-up van 12,7 seconden naar 2,3 seconden.

Wat we eruit haalden

  • Elke laag die slaapt, moet het erover eens zijn wat blijft bestaan. Een bevroren app en een slapende database maakten elk een redelijke keuze. Samen werd de app wakker met een staat die niet meer waar was.
  • Standaarden die voor altijd-aan-servers zijn ontworpen, passen niet bij apps die naar nul schalen. Verbindingen warm houden is een goed idee tot alles eromheen koud wordt.
  • Geef frameworks hun data in hun eigen formaat. Eén URL was eenvoudig voor ons en dwong elke Spring-app om een pool met de hand te bouwen die zijn eigen configuratie negeerde.
  • Test dat een instelling is gespeld zoals het framework haar leest. Een juiste waarde onder de verkeerde naam doet stilletjes niets.

Als je nieuw bent in hoe databases op Mythex werken, zie de databasedocumentatie en onze uitleg over wat Postgres is.

Mythex · Pricing · Bouw alles met AI · Website- en app-templates · Mythex vergeleken · Woordenlijst voor apps bouwen met AI · Gratis tools voor apps bouwen met 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 ਪੰਜਾਬੀ 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 简体中文 繁體中文(香港) 繁體中文(台灣)