Нагрузкове тестування серверних модулів ігор
Сервер гри поводиться зовсім по-іншому під навантаженням, ніж в розробці. На 10 підключеннях все летить. На 500 — з'являються перші race conditions в lobby-менеджері. На 2000 — connection pool Postgres закінчується, і матчмейкинг починає віддавати 503 з затримкою 8 секунд. Нагрузкове тестування — це не стрес-тест заради стресу, а пошук конкретної точки деградації та розуміння того, що саме ламається першим.
Типові вузькі місця в серверній архітектурі ігор
Матчмейкинг під навантаженням. Логіка пошуку матчу часто реалізована як періодичний опитування БД: кожні 500 мс вибрати гравців з черги, сформувати кімнату, оновити статуси. При 1000 одночасних гравців в черзі це 1000 UPDATE-запитів кожні пів секунди плюс SELECT з GROUP BY по ratings. Без індексу на (status, rating, created_at) запит починає робити seq scan по таблиці в 500k рядків — і час відповіді зростає нелінійно.
Синхронізація стану. Серверний ігровий цикл (tick loop) повинен обробляти вхідні события від усіх клієнтів та розсилати оновлення. При tick rate 30 Гц та 64 гравцях у матчі це 1920 вхідних повідомлень в секунду на один інстанс. Якщо обробка не паралельна, а через одну чергу, то при додаванні важкої ігрової логіки (raycast-перевірки попадань, pathfinding) tick починає просідати і клієнти отримують рассинхрон.
Session store. Redis зазвичай справляється з ігровими сеансами — але тільки якщо ключі правильно спроектовані. Зберігати весь об'єкт PlayerState розміром 50 КБ в одному Redis-ключі та оновлювати його цілком кожен tick — погана ідея. При 500 активних матчах це 500 × 64 × 30 = 960,000 записів в секунду по 50 КБ кожна. Redis просто не витягне. Правильно: зберігати тільки delta або розбивати на дрібні поля з окремим expire.
Як ми проводимо нагрузкове тестування
Перший крок — визначення цільових метрик: скільки одночасних підключень, який 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
Для імітації реального ігрового трафіку пишемо bot-клієнти — скрипти, які підключаються до сервера, авторизуються, виконують типові ігрові дії (рух, стрільба, pikapредметів) в рандомізованому темпі. Це важливіше, ніж просто нагрузити HTTP-endpoints, тому що ігрові сеанси мають специфічний паттерн трафіку: burst при початку матчу, steady state під час гри, burst при завершенні.
На одному проекті — браузерна MMO стратегія — ми виявили, що сервер падав не від кількості підключень, а від конкретної дії: «атака на чужий місто» запускала ланцюг з 14 послідовних DB-запитів у транзакції без savepoints. При 200 одночасних атаках таблиця battles блокувалась на 3–4 секунди, що каскадно гальмувало всі інші операції. Рішення: CQRS, винесення розрахунку результату атаки в окрему job-чергу, асинхронна нотифікація.
Етапи нагрузкового тестування
Спочатку — baseline: замір метрик при нульовому навантаженні та при 10% від цільового онлайна. Це точка відліку.
Потім — ramp-up тест: поступове збільшення навантаження з 10% до 150% від цільового значення з кроком 10–15 хвилин. Фіксуємо, де починається деградація.
Soak test: цільове навантаження протягом 2–4 годин. Виявляє витоки пам'яті, накопичення з'єднань, деградацію через фрагментацію heap.
Spike test: різкий стрибок навантаження в 3–5 разів вище норми (імітація серверного анонса або вірусного приросту). Перевіряє autoscaling та поведінку при перевантаженні.
Після кожного тесту — аналіз flame graph, query explain plans, метрик Redis/Postgres та конкретні рекомендації з оптимізації.
| Обсяг | Орієнтовні терміни |
|---|---|
| Аудит + baseline measurement | 3–5 днів |
| Повний цикл нагрузкового тестування | 2–3 тижні |
| Тестування + оптимізація + повторний прогін | 4–6 тижнів |
Вартість розраховується після аналізу серверної архітектури та цільових показників навантаження.





