Уроци от търкаляне на (средноголеми уеб) приложения в продукция
* Какво (и как) да мерим
* Кога да мерим изобщо 🙈
* За какво да внимаваме в продукция
* Infrastructure-friendly apps
* Cost-saving & друга мешана скара
Уроци от търкаляне на (средноголеми уеб) приложения в продукция Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Отгоре-отгоре Какво (и как) да мерим Кога да мерим изобщо За какво да внимаваме в продукция Infrastructure-friendly apps Cost-saving & друга мешана скара Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Модерно observability Front-end, backend, analytics RUM (Real user monitoring) (Distributed) Tracing APM Unified view / single pane of glass Сервирано с дресинг от маркетинг сосове Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Размерът има значение Колкото по-голямо (или "важно"), толкова повече грижа ще изисква. За хоби проекти и тепърва прохождащи неща, няма голямо значение. За по-големи проекти, всяка минута downtime, или дори забавяне в заявките, са от значение. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Къде сте вие? Не се престаравайте. Прегърнете прагматизма! (Мързела ) Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
За контекст (Dext Prepare) Уеб заявки: 100 мил./седмица, 10 хил./минута, 160 в секунда. 10-15к уникални потребителя, цъкащи из сайта в рамките на 30 минути през "деня". 2 TB основна база (PostgreSQL), иначе няколкостотин TB данни из S3 кофи. Деплойват се промени по няколко пъти на ден (zero-downtime). Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
/cpanel/index.php 30-ина уеб сървиса (over HTTP) и един основен user-facing web app Контейнеризирани Търкалят се в home-grown Kubernetes cluster В AWS Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Като си говорим за downtime... 7 минути downtime за цялата 2022 г. Това включва и 3 пълни смени (upgrade) на базата. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
По темата уроци и downtime... "Поуки от 15 години инциденти в продукция": Слайдове | Видео Но днес ще говорим за друго Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Разбиране на всяко звено от стека 1. Load balancer, ако има 2. App server (puma, passenger, ...) 3. App code (Rails) + deployment модела ви (процеси, нишки, ...) 4. Обикновено има и още. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Как е при нас 1. AWS Application Load Balancer 2. Nginx като L7 per-request LB (работещ на група от няколко машини) 3. Nginx вътре във всеки app pod 4. Puma или Passenger 5. Rails + app code Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Всяко с неговите си Таймаути Лимити (на headers, bodies) Кой как, какво и кога буферира Кое как се чупи и какви грешки генерира Всяко звено продуцира метрики и логове, които може да ви интересуват Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
To buffer or not to buffer? Буферирането "забавя" – в Релсата пристига "готов" request Понякога яде повече памет (разумните буфериращи неща пазят във файл от един размер нагоре) Искам ли го изобщо? Обикновено да. Пази ви от т.нар. "slow clients" Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Deployment models Всеки от следващите може да ползва и предишните: 1. Multi-process 2. Multi-threaded 3. Event-based Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Deployment models Всеки от следващите може да ползва и предишните: 1. Multi-process 2. Multi-threaded ← Rails is stuck here 3. Event-based ← Falcon #хубавоенонееготово Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Как е при нас Смесица от multi-process (Dext Prepare) и multi- threaded (други по-малки апове) Разгледахме Falcon (async/evented сървър), но на практика не ни огря Отскоро имаме и event-based неща, ама са на nodejs Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Мониториране Всеки deployment model си има особености за мониториране. Multi-process е най-простият и лесен. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Какво да следя? 1. Uptime (UptimeRobot or whatever) 2. Error tracking (по имейл, или някоя услуга – Sentry, Bugsnag, HoneyBadger, ...) 3. Логове на всяко от звената по пътя 4. Метрики от (повечето) звена по пътя ← ние сме тук 5. APM 6. Tracing 7. Ad-hoc/realtime profiling/troubleshooting Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Uptime Нещо външно (за вашата инфра) ви пингва на всеки Х минути и ви известява, ако не успее да получи желаният резултат Добре е да пази история и статистика, поне за вътрешна употреба Бонус: да може да покаже публичен uptime/status page Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Error tracking Може дълго време да избутате с грешки по имейл ...до момента, в който ви избухне пощенската кутия от някой хахо, който ви бомби сайта с глупости Error tracking services имат смислена употреба Внимавайте за квотата им и какво става, когато я достигнете Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Логове – златната мина Може да стигнете много далеч само с логове APM и tracing си имат цена (за нея – след малко) Важно: от всяко звено! Poor-man's-APM, ако логвате и неща като CPU & mem usage per request Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Логове – какво? Времена: целия request (duh), DB, view, external calls Идентификатори и параметри на request/response-а Брой алокации GC.stat[:total_allocated_objects] Diff на паметта: /proc/#{Process.pid}/status CPU burn: Process.clock_gettime с Process::CLOCK_THREAD_CPUTIME_ID Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Метрики – за web requests Времена (сурови и/или percentiles, напр. max, 90th, 95th, 99th) Beware of averages! Брой responses per status code (може и агрегирани) Наличен и "зает" капацитет (полезно за autoscaling) Системни ресурси на вашите звена (CPU, memory, traffic, ...) Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Метрики за фонови задачи Размери на опашките Време на чакане (възраст на най-стария job) Време на обработка Наличен и "зает" капацитет Системни ресурси на вашите звена (CPU, memory, traffic, ...) Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
APM & tracing Не са "безплатни" (memory, CPU, traffic, storage, ...) "Какво искам да виждам?" Ако ще го правите, търсете tail-based sampling (сигурно искате да виждате с приоритет най- бавните си заявки) И умната Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
За какво да внимаваме в продукция 1. Rate-limits 2. Circuit-breakers 3. Memory usage & bloat 4. Гневни админи Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Infrastructure-friendly apps Или: как да пазим админите от дълбока депресия. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Easy to maintain code https://12factor.net/ Поддържайте graceful shutdown ( TERM ) (не е толкова лесно, колкото звучи) async > sync Внимавайте за паметта Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Memory bloating File.read(...) не четете файлове наведнъж IO.copy_stream е ваш приятел (streaming) JSON parsing Lots of AR objects vs сурови DB resultsets и POROs Винаги с лимит и/или обработвайте на бачове "Рестартирай и ще се оправи" (process recycling) Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Rate limits (за външни APIs) Или, що е то "SMS pumping fraud" Twilio "инцидента", който ни струва $40k. Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Cost-saving Деликатният баланс: cost vs availability Queueing (& waiting) vs early errors Autoscaling, spot машини и подобни Use the ARM, Luke! Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext
Kъде бих хоствал аз 1. Статичен сайт! (GitHub Pages, render.com, S3...) 2. render.com > heroku.com, но и Heroku става. 3. Any VPS (AWS Lightsail anyone?) или на домашния Raspberry Pi 4. AWS/GCP/whatever-floats-your-boat 5. Bare metal? 6. Psst: no Ruby Banitsa Ruby Banitsa 2023-03-06 – by 2023-03-06 – by @mitio @mitio от от Dext Dext