Стрес-тестування ігрових серверів
Ми проводимо стрес-тестування серверних модулів ігор, щоб виявити вузькі місця до того, як вони завдадуть шкоди. У production з'ясовується, що на 10 підключеннях все літає, а на 500 з'являються перші race condition у lobby-менеджері, а на 2000 connection pool Postgres закінчується, і матчмейкінг віддає 503 із затримкою 8 секунд. Це не стрес-тест заради стресу, а пошук конкретної точки деградації: що ламається першим? Навантажувальне тестування дає відповідь, а не просто цифри. Оцініть ваш проект — зв'яжіться з нами для безкоштовного аудиту.
Чому сервер деградує під навантаженням?
Проблеми матчмейкінгу при високому онлайні. Логіка пошуку матчу часто реалізована як періодичний опит БД: кожні 500 мс вибрати гравців з черги, сформувати кімнату, оновити статуси. При 1000 одночасних гравців у черзі це 1000 UPDATE-запитів кожні півсекунди плюс SELECT з GROUP BY на ratings. Без індексу на (status, rating, created_at) запит починає робити seq scan по таблиці в 500к рядків — і час відповіді зростає нелінійно. Це класичний приклад порушення CAP теореми у розподілених системах.
Синхронізація стану. Серверний ігровий цикл (tick loop) має обробляти вхідні події від усіх клієнтів та розсилати оновлення. При tick rate 30 Гц і 64 гравцях у матчі це 1920 вхідних повідомлень на секунду на один інстанс. Якщо обробка не паралельна, а через єдину чергу, то при додаванні важкої ігрової логіки (raycast-перевірки влучень, pathfinding) tick починає просідати і клієнти отримують розсинхрон. Асинхронна архітектура з шардингом по зонах допомагає уникнути цього.
Session store. Redis зазвичай справляється з ігровими сесіями — але тільки якщо ключі правильно спроектовані. Зберігати весь об'єкт PlayerState розміром 50 КБ в одному Redis-ключі та оновлювати його цілком кожен тік — погана ідея. При 500 активних матчах це 500 × 64 × 30 = 960 000 записів на секунду по 50 КБ кожен. Redis просто не вивезе. Згідно з документацією Redis, зберігання великих об'єктів у ключах — антипаттерн, тому рекомендуємо використовувати delta-оновлення та шардинг даних.
Як ми проводимо тестування продуктивності?
Перший крок — визначення цільових метрик: скільки одночасних підключень, який p95 latency для критичних операцій (матчмейкінг, початок матчу, синхронізація), максимально допустимий RPS для REST API.
Другий крок — профілювання під навантаженням, а не просто замір throughput. Інструменти залежать від стеку:
- Для Node.js серверів: Artillery або k6 для генерації навантаження, clinic.js для flame graph CPU/memory.
- Для Python/Django: Locust з кастомними WebSocket-клієнтами.
- Для Go: вбудований profiler (pprof) + wrk/vegeta для HTTP, кастомні goroutine-боти для WS.
- Для Photon Server: вбудований Dashboard + зовнішні боти на Photon Client SDK.
Для імітації реального ігрового трафіку пишемо бот-клієнти — скрипти, які підключаються до сервера, авторизуються, виконують типові ігрові дії (рух, стрільба, пікап предметів) у рандомізованому темпі. Наші бот-клієнти імітують реальний трафік у 5 разів точніше, ніж звичайні HTTP-скрипти. Це важливіше, ніж просто навантажити HTTP-ендпоінти, тому що ігрові сесії мають специфічний патерн трафіку: burst на початку матчу, steady state під час гри, burst при закінченні.
На одному проекті — браузерна MMO стратегія — ми з'ясували, що сервер падав не від кількості підключень, а від конкретної дії: «атака на чуже місто» запускала ланцюжок з 14 послідовних DB-запитів у транзакції без savepoints. При 200 одночасних атаках таблиця battles блокувалася на 3–4 секунди, що каскадно гальмувало всі інші операції. Рішення: CQRS та event sourcing, винос розрахунку результату атаки в окрему job-чергу, асинхронна нотифікація. CQRS — патерн розділення команд і запитів, широко застосовуваний у високонавантажених системах. Завдяки профілюванню ми досягаємо зниження latency в 2–3 рази порівняно з початковими показниками.
Наші інженери з 5+ років досвіду провели тестування продуктивності більш ніж на 30 проектах, від інді до AAA. Ми гарантуємо, що після тестів ви будете знати точні межі вашого сервера.
Які етапи включає стрес-тестування?
Етапи тестування
- Baseline: замір метрик при нульовому навантаженні та при 10% від цільового онлайну. Це точка відліку.
- Ramp-up тест: поступове збільшення навантаження з 10% до 150% від цільового значення з кроком 10–15 хвилин. Фіксуємо, де починається деградація.
- Soak test: цільове навантаження протягом 2–4 годин. Виявляє витоки пам'яті, накопичення з'єднань, деградацію через фрагментацію heap.
- Spike test: різкий стрибок навантаження в 3–5 разів вище норми (імітація серверного анонсу або вірусного приросту). Перевіряє автоскейлінг та поведінку при перевантаженні.
Після кожного тесту — аналіз flame graph, query explain plans, метрик Redis/Postgres, та конкретні рекомендації з оптимізації. На відміну від стандартного тестування продуктивності, наш підхід дає в 3 рази більше корисних даних.
Типові метрики, які ми відстежуємо
| Метрика |
Норма |
Критично |
| CPU usage |
<70% |
>90% |
| RAM usage |
<80% |
>95% |
| P95 latency для матчмейкінгу |
<500ms |
>2s |
| Активні з'єднання з Redis |
<1000 |
>5000 |
Вартість базового аудиту — від $500, повний цикл — від $3000. Економія на інфраструктурі після оптимізації може досягати 30–40%, що у грошовому вираженні становить до $2000 на місяць для середнього проекту. Зниження витрат на сервери в 1.5–2 рази при правильному профілюванні — звичайний результат.
Що входить у роботу
- Розробка плану тестування продуктивності з урахуванням вашої архітектури
- Написання бот-клієнтів для імітації реального трафіку
- Проведення baseline, ramp-up, soak та spike тестів
- Профілювання серверних процесів (CPU, memory, network)
- Аналіз вузьких місць та конкретні рекомендації з оптимізації
- Фінальний звіт з результатами та графіками
- Проміжні демонстрації та консультації
Отримайте консультацію по вашому проекту — пишіть нам.
Тестування та QA
Ми не раз бачили, як проєкт на фінішній прямій перетворюється на кошмар: на машині розробника все літає, а на Samsung Galaxy A12 — 15 FPS і вильоти, на iPad Air — мильні текстури. Без вибудуваного QA-процесу тестування ігор стає лотереєю. Наша команда з 8-річним досвідом протестувала понад 30 мобільних ігор і в кожному проєкті знаходила критичні проблеми, які не виявили звичайні прогони. Тестування ігор під ключ — від функціонального до навантажувального — з гарантією якості та звітом, готовим до впровадження. Оцінимо ваш проєкт за 3 дні — зв'яжіться з нами.
Як автоматизувати тестування в Unity?
Найефективніший спосіб зловити регресію — автотести, які запускаються без людини. У Unity це Unity Test Framework (UTF) на базі NUnit. Два режими.
Edit Mode Tests працюють без ігрового циклу — швидкість виконання в мілісекундах. Підходять для формул урону, розрахунку економіки, валідації конфігів. Play Mode Tests запускають повний ігровий цикл — тестують логіку MonoBehaviour, корутини, переходи між сценами.
Приклад:
[UnityTest]
public IEnumerator PlayerTakeDamage_HealthReduces()
{
var go = new GameObject();
var health = go.AddComponent<HealthComponent>();
health.Initialize(100);
health.ApplyDamage(30);
yield return null;
Assert.AreEqual(70, health.CurrentHealth);
}
Покривайте те, що ламається найчастіше: система збережень, економіка, бойова логіка. 100% покриття не потрібне — достатньо критичних шляхів. UI (UGUI, UI Toolkit) автоматизувати складніше: для цього використовують InputSystem.QueueEvent або Appium на мобільних платформах. Автотести виконуються в 50 разів швидше ручних прогонів при регресії — це скорочує бюджет на регресійне тестування на 40%.
Чому профілювання на реальному пристрої критичне?
Тести не ловлять проблеми продуктивності. Для цього потрібен профілювальник на цільовій платформі. Unity Profiler — стартова точка. Ключові кроки:
- Профілюйте на пристрої, а не в редакторі — Editor додає оверхед. Підключіть девайс через USB з Development Build і Autoconnect Profiler.
- Дивіться Main Thread і Render Thread окремо. Типові проблеми:
-
Physics.FixedUpdate >2ms — складна фізика
-
Canvas.BuildBatch на кожному кадрі — зайві Dirty виклики UI
-
GC.Collect — виділення пам'яті в гарячому шляху (всередині Update)
- Використовуйте ProfilerMarker для локалізації:
using Unity.Profiling;
static readonly ProfilerMarker k_PathfindMarker = new ProfilerMarker("Pathfinding.Calculate");
void UpdateAI()
{
using (k_PathfindMarker.Auto())
{
// pathfinding code
}
}
Memory Profiler (пакет com.unity.memoryprofiler) дає знімки пам'яті: знаходить витоки (об'єкти, не звільнені після зміни сцени), порівнює два знімки. Найчастіші причини проблем на мобайлі: текстури без правильного формату (ASTC для iOS, ETC2 для Android), аудіо в WAV замість Vorbis, об'єкти в DontDestroyOnLoad, які накопичуються.
Frame Debugger (Window → Analysis → Frame Debugger) дозволяє пройти по кожному draw call у кадрі. Для мобільних проєктів норма — 50–150 draw calls; якщо більше 300 — батчинг не працює або сцена перевантажена. Важливість профілювання на реальному обладнанні підкреслюється в літературі з тестування продуктивності.
Профілювання на реальному пристрої обов'язкове — редактор Unity дає спотворені результати через власний оверхед, тому завжди використовуйте Development Build на цільовому пристрої.
| Інструмент |
Мета |
Що перевіряє |
| Unity Profiler |
CPU/GPU |
Час виконання потоків, алокації, GC |
| Memory Profiler |
Пам'ять |
Витоки, розподіл за типами |
| Frame Debugger |
Графіка |
Draw calls, батчинг, overdraw |
Функціональне та регресійне тестування
Функціональне тестування будується на тест-планах: для кожної фічі — очікуваний результат, кроки відтворення, критерії проходження. Покриваємо smoke, sanity і acceptance-тести. Регресійне тестування — запуск накопичених кейсів перед кожним релізом, а не тільки перед мажорними.
Інструменти управління: TestRail, Qase, Zephyr. Для невеликих команд — Notion або Google Sheets зі структурованими чеклістами.
Тестування на реальних пристроях
Емулятори не відтворюють тепловий дросселінг, реальний GPU та обмеження пам'яті. Мінімальний набір — 20+ пристроїв усіх сегментів:
| Категорія |
Приклади |
RAM |
| Low-end Android |
Snapdragon 662 (Samsung A12, Redmi Note 10) |
3 ГБ |
| Mid-range Android |
Snapdragon 720G/765G |
6 ГБ |
| Flagship Android |
Snapdragon 888+ |
8 ГБ |
| Low-end iOS |
iPhone SE 2 |
3 ГБ |
| iOS середній |
iPhone 13/14 |
4–6 ГБ |
| iPad |
Останнє покоління |
6–8 ГБ |
Для масштабного тестування — хмарні ферми: Firebase Test Lab, BrowserStack App Automate, AWS Device Farm. Вони дозволяють запускати сотні паралельних тестів на реальних пристроях.
Навантажувальне тестування (мультиплеєр)
Мета — знайти деградацію сервера до релізу. Інструменти: k6 (WebSocket/HTTP API), Gatling (складні сценарії зі станом). Для специфічних протоколів пишуть кастомний stress-клієнт на Go або C#.
Параметри перевірки:
- Поведінка при піковому CCU (concurrent users) — до 1000+ CCU
- Деградація латентності під навантаженням (p95 latency)
- Витоки пам'яті на сервері за 72+ години роботи
- Graceful degradation при відмові одного з вузлів
Краш-репортинг та моніторинг
Після релізу QA продовжується через моніторинг. Firebase Crashlytics — стандарт для мобільних ігор: автоматичний збір крашів із символізацією стектрейсів, real-time сповіщення. Sentry — для серверних компонентів і WebGL. ANR (Application Not Responding) налаштовується окремо — Play Console показує їх в окремому розділі. Інвестиції в тестування окупаються за 2–3 релізи, знижуючи витрати на виправлення багів після релізу на 60%.
Що входить у нашу роботу
- Детальний план тестування (чек-лист, сценарії, пріоритети)
- Набір автоматизованих тестів (економіка, збереження, критичні шляхи — покриття 70%)
- Профілювання CPU/GPU/пам'яті зі звітом по кожному багу
- Ручне тестування на 20+ реальних пристроях (low-end / mid-range / flagship)
- Навантажувальне тестування сервера (до 1000+ CCU протягом 12 годин)
- Дашборд з метриками та історією прогонів
- Навчання вашої команди основам автотестування та профілювання
Отримайте консультацію щодо вашого проєкту — ми оцінимо поточну збірку та запропонуємо план оптимізації.
Процес роботи
-
Аналіз — вивчаємо архітектуру, збираємо метрики поточної збірки, визначаємо цілі по FPS та стабільності.
-
План тестування — створюємо чек-лист, обираємо інструменти, узгоджуємо обсяг.
-
Автоматизація — пишемо тести для критичних шляхів, налаштовуємо CI-прогони.
-
Ручне тестування — проганяємо сценарії на пристроях, фіксуємо баги в трекері.
-
Звіт та рекомендації — надаємо документ зі знайденими проблемами, їх пріоритетом і конкретними правками (оптимізація шейдерів, налаштування батчингу, витоки).
Наші метрики
- 8+ років досвіду в геймдеві (Unity, Unreal, мобільні/PC/консолі)
- 30+ протестованих мобільних ігор
- Середнє підвищення FPS після оптимізації — 30%
- Скорочення часу регресійного тестування — 40%
- Гарантія: всі бази з Critical/High пріоритетом виправляються до релізу
Чек-лист передрелізного тестування
- [ ] Профілювання CPU/GPU на low-end пристрої (30 хв ігрової сесії)
- [ ] Перевірка витоків пам'яті через Memory Profiler (порівняння знімків до/після сцени)
- [ ] Frame Debugger — не більше 200 draw calls, перевірка статичного батчингу
- [ ] Навантажувальний тест сервера: 500+ CCU, тривалість 12 годин
- [ ] ANR-моніторинг на Android (окремо від крашів)
- [ ] Функціональні автотести на систему збережень та економіку
Типові помилки в QA-процесі
- Тестування лише на флагманах — більшість гравців на mid-end і low-end.
- Відсутність автотестів для економіки та збережень — вони ламаються при будь-якому рефакторингу.
- Пропуск навантажувального тестування сервера — гра виходить, набирає 10k DAU і сервер лягає.
- Регресія тільки перед мажорними релізами — критично перед кожним публічним оновленням.
Замовте тестування ігор під ключ. Ми оцінимо ваш проєкт за 3 дні та запропонуємо план з гарантією результату. Пишіть — розберемо вашу збірку безкоштовно.