Одного ранку до нас звернувся клієнт: у нього спрацював алерт. Разом ми почали розбиратися, що сталося. Мікросервіс гейміфікації, який зазвичай живе на двох POD, раптом заскейлився до десяти і не збирався скейлитися назад. Трафік був стабільно високий, але жодної акції та органічного росту – нічого, що пояснювало б стрибок.
Логи і referer у межах норми – сервіс живе на тому ж домені, що й основний продукт, тому виглядає як «свій» трафік. Причину бачимо, лише коли самі заходимо на основний продукт у меню. Там з’явився новий віджет із кількістю спроб користувача. Інтеграцію ми узгоджували, але деталь, яка вистрілила, у документ не потрапила. Віджет викликав ендпоінт при кожному завантаженні сторінки, навіть коли нагород у користувача не було і віджет мав порожній стан.
Ми поставили на цей ендпоінт кеш на Cloudflare з TTL у 3 секунди і навантаження одразу зменшилося. Залишили це як тимчасовий фікс, поки фронт не додав умову «не відправляти запит, якщо нагород немає». Жодного інциденту на боці користувачів не було, адже HPA відпрацював, алерт прилетів тоді, коли ще нікому не було боляче.
Ця історія добре ілюструє, як виглядає робота з highload у реальності. Підготовка до пікових навантажень не означає просто докинути ресурсів перед подією. Тут йдеться про архітектуру, бази, інтеграції, моніторинг і готовність помітити дивну поведінку системи раніше, ніж її помітять користувачі. Й у партнерській статті розкажемо, як ми в SharksCode організували процес.
Зміст
З якими піками ми працюємо
Наші клієнти створюють продукти, де сплески трафіку є частиною бізнес-моделі. Найчастіше ми готуємося до:
- великих спортивних подій на платформах клієнтів – футбол, кіберспорт, live betting;
- jackpot- і bonus-кампаній;
- партнерських та реферальних акцій.
Під час популярного live-матчу платформа клієнта може отримати близько 50 000 одночасних сесій, до 10 000 RPS на API та різкі сплески write-навантаження. Такі піки короткочасні, але дуже інтенсивні, тому ми моделюємо їх заздалегідь.
Пікові сценарії у наших клієнтів завжди різні. Десь це мільйон RPS, десь – 500 користувачів, але зі складними транзакціями. Тому ми не прив’язуємося до абстрактних цифр та говоримо про готовність системи до навантаження, яке є граничним саме для неї.
Що ми тестуємо перед піком
Тестування починається з того, що ми з клієнтом відтворюємо реальні дії користувача, а не синтетичні: логін, верифікацію, серію ставок, інше. Кожен такий ланцюжок є каскадом дій з очікуваною послідовністю, і саме його ми відтворюємо в тестах.
Критичність сценаріїв визначаємо за трьома факторами: бізнес-метрики, історичні дані (які ендпоінти генерують 70–80% реального трафіку) і критичність транзакцій (де втрата чи дублювання запиту коштуватиме платформі репутації).
З інструментів використовуємо для тестів два:
- k6 для швидких і повторюваних тестів, які добре вбудовуються в CI/CD і Grafana;
- Locust, коли потрібно змоделювати складні user flows або масштабувати генерацію трафіку через розподілені агенти.
Найретельніше перевіряємо API (latency і throughput), бази даних (connections, locks, replication lag), черги (Kafka/RabbitMQ) та інтеграції, особливо з платіжними провайдерами. Причина в тому, що більшість інцидентів – це ланцюгова реакція затримок, а не падіння одного сервісу.
Готовність до піку оцінюємо за чіткими SLO: p95 latency < 200 мс, error rate < 0,5%, CPU/RAM < 80%, throughput ≥ 80% від очікуваного піку. Працюємо через error budget, і якщо він вичерпаний, релізи блокуються.
Є й речі, які ми свідомо не тестуємо, як-от довготривалі навантаження та рідкісні edge-кейси. Вартість таких тестів не виправдовує користі. Замість них покладаємося на synthetic monitoring і production observability.
Підготовка до піку по днях
За 2–3 дні до піку
За кілька днів до піку ми запускаємо фінальні load-тести на конфігурації, максимально наближеній до продакшену. Перевіряємо capacity, а саме, чи є запас по ресурсах у кластері, чи не впираємося в ліміти ноди. Вмикаємо freeze на зміни: ні коду, ні конфігів не деплоїмо без надкритичної потреби. Окремо проганяємо failover-сценарії та перевіряємо бекапи. Усе формалізовано в runbook, тому що імпровізації на цьому етапі не має бути.
За ~24 години до події
Приблизно за добу до піку ми тестуємо самі алерти: чи Grafana дійсно відправляє повідомлення в PagerDuty, чи не зламався канал нотифікацій. Переглядаємо дашборди, робимо dry-run on-call, проходимо escalation chain – хто кому передає інцидент, якщо primary-інженер не відповідає. Банальні речі, але саме на них система валиться у найневдаліший момент, якщо не перевірити.
Останні кілька годин перед піком
Коли до піку залишаються лічені години, наше головне завдання – мінімізувати кількість невідомих. DevOps в цей час займається preheat-скейлінгом: заздалегідь вказує мінімальну кількість POD до очікуваного рівня, щоб не чекати, поки HPA відреагує вже під навантаженням. Ті 30–60 секунд на scale у момент піку перетворюються на реальні помилки для користувачів.
Паралельно перевіряємо можливості скейлінгу баз даних. Для Aurora це запас по інстанс-класу і навантаження read replicas. Для Atlas – auto-scaling і ліміти тіру. Краще підняти ресурси заздалегідь і знизити після, ніж ловити деградацію під навантаженням.
Обов’язково проходимося по поточних інцидентах, як-от незакриті баги, нестабільні сервіси, нещодавні деплої, які ще не перевірені реальним трафіком. Якщо щось викликає сумніви, відкочуємо або готуємо план Б. І окремо відбувається фінальна перевірка моніторингу та алертів.
В останні години перед піком фокусуємося виключно на дисципліні. Чим менше буде сюрпризів, тим спокійніше для нас.
Що відбувається в момент піку
У момент навантаження кожен у команді знає свою зону відповідальності, і саме тому нічого не провалюється між ролями. DevOps слідкують за інфраструктурою (стан кластера, скейлінг, ресурси), backend-команда моніторить сервіси, логи і час відповіді, DBA тримає руку на пульсі баз: slow queries, connection pool, реплікація.
On-call організовано через Grafana OnCall з ротацією primary + backup і ескалацією до Architect або CTO. Під час великих подій чергування подвоєне: один інженер не закриває всі ризики, і другий страхує першого. Комунікація відбувається в окремому каналі інциденту, куди автоматично приходять алерти і де команда у реальному часі обмінюється контекстом.
Які метрики ми дивимось у реальному часі
Під час піку у нас є чітка ієрархія того, куди дивитися і в якій послідовності.
Перший рівень – бізнес-симптоми. Error rate і latency на рівні API. Ці метрики першими сигналізують, що щось пішло не так з погляду користувача, а не заліза.
Другий рівень – бази даних. Активні з’єднання, slow queries, replication lag. База першою починає страждати під навантаженням, а зовнішні симптоми з’являються пізніше. Якщо ловити їх тільки на рівні API, реакція буде запізнілою.
Третій рівень – CPU і RAM. Важливі, але скоріше як індикатор для скейлінгу. Поди можуть їсти 90% CPU і нормально відповідати або споживати мало ресурсів і висіти на очікуванні з’єднання до бази. Тому ці метрики читаємо в парі з першими двома рівнями.
Інструменти, що використовуємо під час піку: Grafana з Prometheus як основним datasource (окремі дашборди під API, БД і черги), Kibana для логів, Datadog з custom-дашбордами для бізнес-метрик.
Як система і команда реагують на інциденти
Резервування закладене на кожному рівні:
- Kubernetes – auto-scaling подів і вузлів кластера;
- бази даних – Aurora з read replica і автоматичним failover та Atlas з replica set;
- Istio – circuit breakers і retry-політики на рівні service mesh;
- Cloudflare – як CDN і швидкий інструмент кешування в екстрених випадках.
Якщо primary падає, перемикання відбувається без ручного втручання. Але автоматика – ще не все. Алгоритм дій для інженера, який реагує на інцидент, має виглядати так:
- Зрозуміти масштаб. Скільки користувачів зачеплено, які сервіси деградують, чи є фінансовий вплив.
- Стабілізувати, а не лагодити. Якщо є швидке рішення – відкат деплою, скейлінг, увімкнення fallback – робимо його першим.
- Root cause шукаємо потім, коли система стабільна. Якщо намагатися одночасно гасити пожежу і розбиратися, чому загорілося, це тільки погіршить ситуацію.
Найшвидше ми закривали інцидент за 4 хвилин – від звернення клієнта до повного розв’язання проблеми. Під час піку зафіксували сплеск навантаження на API, але система швидко відреагувала: спрацювали circuit breaker і автоскейлінг подів. Допомогли автоматизація в Istio та заздалегідь підготовлені runbooks.
Головні уроки роботи з highload
- Моніторимо бізнес-метрики, а не інфраструктуру. Раніше дивилися на CPU, RAM, кількість подів – зелене означає, що жодна з метрик не виходила за допустимі межі, тож здавалося, що все працює нормально. Але CPU може бути 30%, а користувач уже не може провести оплату, бо вичерпаний connection pool. Зараз ми алертимо error rate, latency критичних ендпоінтів, queue lag. Інфраструктурні метрики стали другорядними.
- Performance safari. Раз на спринт розробник проходить по метриках свого сервісу – дашборди, логи, профілі запитів – і шукає потенційні слабкі місця до того, як вони з’являться на проді.
- Під час інтеграцій проговорюємо поведінку у всіх станах. Історія з віджетом гейміфікації, про який ми розповідали на початку статті, саме про це. Недостатньо домовитись про API, треба ще раз перевірити відповідність коду до sequence діаграм і перевірити флоу різних випадків. Треба проговорювати: що робимо, коли дані відсутні? Коли фіча неактивна? Коли користувач не має доступу? Саме ці очевидні кейси найчастіше і трапляються.
- Код-рев’ю важливіше за будь-яку підготовку. Більшість проблем під навантаженням не є інфраструктурою — це код: N+1 запити, відсутні індекси, запит без таймауту, обробки помилок. Звичка при кожному merge request запитувати себе «а що буде під x2, x5, x10 трафіку?» працює краще за load-тест.
- Завжди має бути швидкий шлях назад. Rollback деплою, feature flag, fallback. Highload-система – це не та, яка ніколи не падає. Це та, яка передбачувано реагує на збої і швидко відновлюється





Повідомити про помилку
Текст, який буде надіслано нашим редакторам: