Събуждане на бази данни без мъртви връзки
Публикуваните приложения в Mythex и техните бази данни заспиват, когато никой не ги ползва. Когато приложение се събуждаше, можеше да държи първата си заявка 10–12 секунди, защото се опитваше да използва повторно връзки към базата данни, които бяха умрели, докато всичко спеше. Сега даваме на Spring Boot приложенията настройки на базата, които са безопасни след сън, и казваме на агента да строи приложения от всеки стек по същия начин. В хостинг платформата първата заявка след събуждане мина от 12,7 секунди на 2,3 секунди.
Защо приложенията и базите заспиват
Публиквано приложение в Mythex работи на машина, която се приспива след няколко минути бездействие, а базата му е serverless Postgres, която заспива след пет минути бездействие и се буди при следващата заявка. Това държи тихото приложение евтино: плащате за това, което базата действително е използвала, а заспалото приложение не харчи нищо за изчисления. За таксуването писахме в таксуване на базите данни според това, което действително използват.
Капанът е, че двете заспиват отделно и не се съгласяват какво е връзка.
Симптомът: бавно първо посещение
Повечето сървърни приложения поддържат connection pool: няколко отворени връзки към базата, държани готови, така че всяка заявка да не плаща цената на отварянето на нова. Това е правилният дизайн за приложение, което е винаги включено.
Ето какво се случва при сън:
- Приложението работи, с няколко неизползвани връзки в пула си.
- Никой не посещава. Машината на приложението се приспива — замръзнала, с пула непокътнат.
- Базата заспива и затваря своя край на всяка връзка.
- Пристига посетител. Приложението се събужда точно както е било, все още държащо връзки, за които базата вече не знае.
- Пулът предава една от тези връзки. Трябва да разбере, че е мъртва — като опита и почака — преди да се откаже от нея.
В Spring Boot приложение валидирането на мъртвите връзки блокираше първата заявка за около 10 секунди, преди да се провали с „Connection is not available“. За посетителя сайтът просто висеше, а после може би показваше грешка.
Защо Spring приложенията пострадаха най-много
Spring Boot е популярна Java рамка и по подразбиране използва пул за връзки, наречен HikariCP. Spring може да конфигурира този пул от настройки, включително колко неизползвани връзки да държи.
Но Mythex дава на всяко приложение базата му като една променлива DATABASE_URL във вида postgresql://user:pass@host/db. Spring не може директно да чете този формат. Затова Spring приложенията, построени в Mythex, сами създаваха пула си в кода, като разбираха този URL — а пул, построен на ръка, игнорира всички настройки spring.datasource.* на Spring. Дори някой да знаеше правилните настройки на пула, нямаше място, където те да влязат в сила.
Поправката, част 1: настройки, които Spring може да ползва
Когато проект има база данни, сега получава и променливи на средата, които Spring чете директно:
SPRING_DATASOURCE_URL,SPRING_DATASOURCE_USERNAMEиSPRING_DATASOURCE_PASSWORD, конвертирани отDATABASE_URL(със SSL задължителен, освен ако URL-ът не казва друго).- Настройки на пула, които оцеляват след сън:
| Настройка | Стойност | Защо |
|---|---|---|
| Минимум неизползвани връзки | 0 | Не се държи нищо отворено между заявките, така че няма какво да остарее |
| Време за неизползване | 30 секунди | Затваря неизползваните връзки скоро |
| Максимален живот | 2 минути | Пенсионира всяка връзка, преди да може да остарее |
| Време за изчакване на връзка | 5 секунди | Не държи заявка дълго, ако базата бави с отговора |
Когато не се държат неизползвани връзки, събуденото приложение отваря една нова връзка, вместо да се бори с мъртвите.
Когато тези променливи присъстват, Spring конфигурира самия пул и настройките важат. Всичко, което проектът е задал сам, винаги има предимство; ние попълваме само липсващото. Приложенията, които не са на Spring, игнорират тези променливи.
Детайлът, който почти я направи безполезна
Spring картографира променливите на средата към своите настройки по правило, което е лесно да сбъркаш. Настройката minimum-idle трябва да се запише като SPRING_DATASOURCE_HIKARI_MINIMUMIDLE — без тирета и с думите слепени. Записана като SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE, която изглежда по-естествено, се картографира към различна, несъществуваща настройка (minimum.idle) и тихо се игнорира.
Това е грешката, която минава през всяко ревю и не прави нищо в продукцията. Затова тест проверява и че стойностите са зададени, и че никоя променлива не ползва форма с долна черта между думите.
Поправката, част 2: всички останали стекове
Spring не е единствената рамка с пул, а не можем предварително да конфигурираме всяка библиотека на всеки език. Затова AI агентът на Mythex, който пише приложението ви, сега получава постоянна инструкция за всеки стек: публикуваните приложения и техните бази заспиват при бездействие, така че връзка, оставена отворена, може да е мъртва при следващата заявка. Той трябва да:
- не държи неизползвани връзки към базата отворени, или да проверява всяка преди употреба,
- опитва отново веднъж при грешка с връзката, и
- използва настройките за базата, които платформата дава в средата, вместо да строи собствен пул, като разбира
DATABASE_URL.
Това последно затваря кръга с част 1: приложение, построено върху предоставените настройки, получава конфигурацията, безопасна след сън, автоматично.
Резултатът
Измерено на хостинг платформата, на която пускаме публикуваните приложения, първата заявка след събуждане мина от 12,7 секунди на 2,3 секунди.
Какво взехме от това
- Всеки слой, който заспива, трябва да се съгласува какво оцелява. Замръзналото приложение и заспалата база направиха всяка разумен избор. Заедно приложението се събуди, държейки състояние, което вече не беше вярно.
- Подразбиранията, проектирани за сървъри, които са винаги включени, не подхождат на приложения, които се мащабират до нула. Държането на връзките топли е добра идея, докато всичко около тях не изстине.
- Давайте на рамките данните им в техния собствен формат. Един URL беше просто за нас и принуди всяко Spring приложение да строи на ръка пул, който игнорираше собствената си конфигурация.
- Тествайте, че настройката е написана така, както рамката я чете. Правилна стойност под грешно име не прави нищо, тихо.
Ако ви е ново как работят базите данни в Mythex, вижте документацията за базите данни и нашето обяснение какво е Postgres.