Blog

Trezirea bazelor de date fără conexiuni moarte

Aplicațiile publicate pe Mythex, și bazele lor de date, intră în somn când nimeni nu le folosește. Când o aplicație se trezea, putea să rețină prima cerere timp de 10–12 secunde, pentru că încerca să reutilizeze conexiuni la baza de date care muriseră cât timp totul dormea. Acum oferim aplicațiilor Spring Boot setări pentru baze de date sigure la somn și îi spunem agentului să construiască aplicațiile din orice stack la fel. Pe platforma de hosting, prima cerere după o trezire a trecut de la 12,7 secunde la 2,3 secunde.

De ce dorm aplicațiile și bazele de date

O aplicație publicată pe Mythex rulează pe o mașină care se suspendă după câteva minute de inactivitate, iar baza ei de date este Postgres serverless, care doarme după cinci minute de inactivitate și se trezește la următoarea cerere. Asta este ce face ca o aplicație liniștită să fie ieftină: plătești pentru ce a folosit efectiv baza de date, iar o aplicație adormită nu consumă nimic pentru calcul. Am scris despre partea de facturare în facturarea bazelor de date după ce folosesc efectiv.

Problema este că cele două dorm separat și nu sunt de acord asupra a ce înseamnă o conexiune.

Simptomul: o primă vizită lentă

Majoritatea aplicațiilor de server păstrează un connection pool: câteva conexiuni deschise la baza de date, ținute gata, ca fiecare cerere să nu plătească costul deschiderii uneia noi. Este designul potrivit pentru o aplicație care rulează permanent.

Iată ce se întâmplă cu somnul:

  1. Aplicația rulează, cu câteva conexiuni inactive în pool.
  2. Nimeni nu o vizitează. Mașina aplicației se suspendă — înghețată, cu pool-ul intact.
  3. Baza de date intră în somn și își pierde capătul fiecărei conexiuni.
  4. Un vizitator sosește. Aplicația se trezește exact cum era, încă ținând conexiuni pe care baza de date nu le mai cunoaște.
  5. Pool-ul îi oferă una dintre aceste conexiuni. Trebuie să afle că e moartă — încercând-o și așteptând — înainte să renunțe la ea.

Într-o aplicație Spring Boot, validarea conexiunilor moarte bloca prima cerere timp de aproximativ 10 secunde, înainte să eșueze cu „Connection is not available”. Pentru vizitator, site-ul pur și simplu atârna, apoi poate afișa o eroare.

De ce aplicațiile Spring au fost cele mai afectate

Spring Boot este un framework Java popular și folosește implicit un pool de conexiuni numit HikariCP. Spring poate configura pool-ul din setări, inclusiv câte conexiuni inactive să păstreze.

Dar Mythex îi oferă fiecărei aplicații baza de date ca o singură variabilă DATABASE_URL, de forma postgresql://user:pass@host/db. Spring nu poate citi direct acest format. Așa că aplicațiile Spring construite pe Mythex își creau singure pool-ul în cod, analizând acel URL — iar un pool construit manual ignoră toate setările spring.datasource.* ale lui Spring. Chiar dacă cineva ar fi știut setările corecte pentru pool, nu exista niciun loc unde ele să aibă efect.

Remedierea, partea 1: setări pe care Spring le poate folosi

Când un proiect are o bază de date, îi oferim acum și variabile de mediu pe care Spring le citește nativ:

  • SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME și SPRING_DATASOURCE_PASSWORD, convertite din DATABASE_URL (cu SSL obligatoriu, dacă URL-ul nu spune altfel).
  • Setări de pool care supraviețuiesc somnului:
SetareValoareDe ce
Numărul minim de conexiuni inactive0Nu ține nimic deschis între cereri, deci nu există nimic care să devină vechi
Timeout pentru inactivitate30 de secundeÎnchide repede conexiunile nefolosite
Durata maximă de viață2 minuteRetrage fiecare conexiune înainte să poată îmbătrâni
Timeout pentru conectare5 secundeNu ține o cerere blocată mult timp dacă baza de date răspunde greu

Fără conexiuni inactive ținute deschise, o aplicație trezită deschide o singură conexiune nouă, în loc să parcurgă conexiuni moarte.

Cu aceste variabile prezente, Spring configurează singur pool-ul, iar setările se aplică. Ce a setat deja proiectul are întotdeauna prioritate; noi completăm doar ce lipsește. Aplicațiile care nu sunt Spring ignoră aceste variabile.

Detaliul care aproape a făcut ca totul să nu aibă niciun efect

Spring mapează variabilele de mediu pe setările sale după o regulă ușor de greșit. Setarea minimum-idle trebuie scrisă ca SPRING_DATASOURCE_HIKARI_MINIMUMIDLE — cratimele eliminate, cuvintele lipite. Scrisă ca SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE, care pare mai natural, se mapează pe o setare diferită, inexistentă (minimum.idle), și este ignorată fără niciun semnal.

Este genul de greșeală care trece prin orice review și nu face nimic în producție. Așa că un test verifică atât că valorile sunt setate, cât și că nicio variabilă nu folosește forma cu underscore între cuvinte.

Remedierea, partea 2: toate celelalte stack-uri

Spring nu este singurul framework cu pool, iar noi nu putem preconfigura fiecare bibliotecă din fiecare limbaj. Așa că agentul Mythex — AI-ul care scrie aplicația ta — primește acum o instrucțiune permanentă pentru orice stack: aplicațiile publicate și bazele lor de date intră în somn când sunt inactive, deci o conexiune ținută deschisă poate fi moartă la următoarea cerere. Ar trebui să:

  • nu păstreze conexiuni inactive la baza de date deschise, sau să verifice fiecare conexiune înainte de utilizare,
  • reîncerce o dată la o eroare de conexiune, și
  • folosească setările pentru baza de date oferite de platformă în mediu, în loc să-și construiască propriul pool analizând DATABASE_URL.

Ultimul punct închide bucla cu partea 1: o aplicație construită pe setările oferite primește automat configurația sigură la somn.

Rezultatul

Măsurat pe platforma de hosting pe care rulăm aplicațiile publicate, prima cerere după o trezire a trecut de la 12,7 secunde la 2,3 secunde.

Ce am învățat

  • Fiecare strat care doarme trebuie să fie de acord asupra a ce supraviețuiește. O aplicație înghețată și o bază de date adormită au făcut fiecare o alegere rezonabilă. Împreună, aplicația se trezea ținând o stare care nu mai era adevărată.
  • Valorile implicite gândite pentru servere care rulează permanent nu se potrivesc aplicațiilor care scalează la zero. A păstra conexiunile calde este o idee bună până când tot ce le înconjoară se răcește.
  • Dă framework-urilor datele în propriul lor format. Un singur URL a fost simplu pentru noi, dar a forțat fiecare aplicație Spring să-și scrie manual un pool care ignora propria configurare.
  • Testează că o setare este scrisă așa cum o citește framework-ul. O valoare corectă sub un nume greșit nu face nimic, în tăcere.

Dacă ești nou în modul în care funcționează bazele de date pe Mythex, vezi documentația despre baze de date și explicația noastră despre ce este Postgres.

Mythex · Pricing · Construiește orice cu AI · Șabloane pentru site-uri și aplicații · Mythex comparat · Glosar pentru crearea de aplicații cu AI · Instrumente gratuite pentru crearea de aplicații cu 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) Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)