Чому система подарунків у мобільній грі ламається на піках
Пік настає не в момент запуску, а коли система подарунків мобільної гри отримує лавину одночасних відправлень: івент, велика розсилка, відкриття сезону.
Клієнт надсилає запит, сервер не встигає підтвердити операцію в строк, клієнт повторює — і замість одного подарунка нараховуються два.
Типові точки розриву — повторне відправлення без ключа операції (дублі нарахувань), списання у відправника без нарахування отримувачу (загублений подарунок, який гравець уже бачить в історії) і зависла операція: відкотити її автоматично не можна, завершити теж.
Окреме джерело дублів — підтвердження покупки в Google Play: платіж проведено, а сервер запитує перевірку повторно й нараховує подарунок вдруге. Жоден із цих збоїв не видно на графіках доступності — падає не сервіс, а коректність обліку подарунків.
Ціна вважається в годинах підтримки: кожна розбіжність — ручний розбір, запит скриншотів, компенсація й правка балансу в базі.
Поки такі випадки поодинокі, їх закривають руками; на піку рахунок іде на сотні звернень, і черга розборів зростає швидше, ніж команда встигає її розгрібати.
Корені зазвичай одні й ті самі: ліміти перевіряються на клієнті, а не на сервері, повтори йдуть без дедуплікації, баланс пишеться синхронно з видачею, а звірки нарахованого та списаного немає взагалі.
Далі розбираємо, як це закривається — від ідемпотентної видачі до черг і push-повідомлень, які не додають навантаження в пік.
Ефект від керованої видачі: що змінюється в цифрах
Частка успішних відправлень перестає залежати від якості зв'язку у гравця. На кожному кроці видачі є підтвердження й повтор із тим самим ключем операції: подарунок або доставлено, або буде доставлено, третього стану немає. Конверсія відправлень зростає без правок у самих правилах гри.
Час відновлення після збою рахується хвилинами, а не хвилею звернень. Черга подарунків переживає перезапуск процесу, ліміти знімаються автоматично, а деградація йде окремими каналами — видача може сповільнитися, але не вимикається повністю. Інженер бачить, який крок відстав, і повертає його точково.
Обсяг ручних звернень у підтримку падає, бо гравець бачить статус подарунка, а не «щось пішло не так». Типові ситуації — не дійшло, прийшло двічі, ліміт на сьогодні — закриваються автоматично, і людині залишаються тільки справжні спірні випадки.
Дублі нарахувань зникають як клас відмов: повторна доставка не створює другий подарунок, а звірка балансів ловить розбіжність раніше, ніж її помітить гравець. Раніше таке розбирали вручну за логами, тепер розбіжностей просто немає.
Усі чотири показники — успішні відправлення, час відновлення, ручні звернення й дублі — знімаємо до та після змін за однією методикою. Так видно, що дав кожен крок: де зросла конверсія відправлень, а де скоротився час повернення в норму.
Варіанти видачі: набір, прямий переказ, обмін
Режим видачі визначає, як предмет покидає каталог предметів і опиняється в інвентарі отримувача. Від нього залежать добові ліміти, облік в історії операцій і те, наскільки просто відкотити помилкову або дублювальну видачу.
Переграти це після запуску майже неможливо: уже видані предмети доведеться мігрувати, а баланс економіки — перераховувати заново.
Режими нижче не взаємовиключні — подарунковий набір часто сусідить із прямим переказом між гравцями, а обмін подарунків живе окремим контуром. Вибирати варто під завдання події та під те, хто ініціює видачу: система за правилом, один гравець або двоє за взаємною домовленістю.
| Режим видачі | Коли підходить | Обмеження |
|---|---|---|
| Подарунковий набір | Святкові події, компенсації, стартові бонуси: склад жорстко описаний каталогом | Немає адресності — набір іде всім за правилом, персональний вибір отримувача недоступний |
| Прямий переказ між гравцями | Внутрішньоігрова валюта, розхідники, подарунки друзям зі списку | Добові ліміти обов'язкові, інакше ресурси перекачуються між акаунтами однієї групи |
| Обмін подарунків | Коли предмети мають повертатися в обіг, а не осідати на складах в отримувачів | Двостороння угода: відкат складніший, потрібен журнал по обох сторонах і перевірка на зустрічні передачі |
Режим видачі фіксується до того, як видано перший предмет: правила лімітів, журнал операцій і логіка відкату описуються в одному місці й не дублюються на клієнті. Тоді додавання нового режиму — розширення правил, а не переробка економіки.
Етапи впровадження: від аудиту до передачі в підтримку
Етапи вибудовані так, щоб кожен наступний крок спирався на перевірений попередній: поки не описано поточний облік, проєктувати схему рано, а ліміти не можна налаштовувати до закриття повторів. Нижче — шлях від першого дня до моменту, коли система живе без нас.
- Аудит обліку. Дивимося, де зберігається баланс відправника, як фіксується вручення і що відбувається при обриві зв'язку між ігровим сервером і платіжним контуром. На виході — карта вузьких місць і список збоїв, які вже трапляються.
- Схема даних. Проєктуємо таблиці подарунків, статусів і журналу операцій з індексами під реальні запити: «що вже отримав гравець», «скільки відправив за добу». Жодна вибірка не читає історію повністю.
- Захист від повторів. Кожному відправленню присвоюємо унікальний ключ операції — повторний запит повертає результат першого, а не створює другий подарунок. Списання й нарахування йдуть в одній транзакції.
- Ліміти. Задаємо межі на відправника, отримувача й пару між ними з добовими та тижневими вікнами. Окремо описуємо поведінку при перевищенні: відмова, черга або перенесення.
- Навантажувальна перевірка. Проганяємо пікові сценарії — святкові події та масові розсилки. Дивимося, чи тримають ліміти, чи не зростає час відгуку і чи залишається журнал повним.
- Навчання підтримки. Передаємо регламенти за типовими зверненнями: подарунок не прийшов, прийшов двічі, ліміт спрацював раніше строку. Показуємо, як за журналом відновити шлях подарунка без правки балансу руками.
- Передача. Закриваємо доступи, налаштовуємо оповіщення про аномалії та домовляємося про реакцію на інциденти. Далі правила й ліміти змінюються штатним порядком, без розбору системи заново.
Що передаємо на руки: конфігурації, схеми, регламенти
У застосунку гравець бачить вітрину, а сам подарунок живе в правилах, лімітах і облікових записах на серверній стороні. Тому на прийманні передаємо не лише збірки, а й описи, за якими ваша команда змінює умови акцій, розбирає спірні нарахування й відповідає гравцям без нас.
- Правила нарахування — таблиця «подія → що і скільки нараховується → що списується» з обумовленими винятками: скасування подарунка, повернення, повторна доставка, недоставлене push-повідомлення.
- Схема обліку — шлях кожного подарунка від відправника до отримувача: статуси, ключ ідемпотентності операції, журнал змін і джерело (гра, промо, підтримка).
- Таблиця лімітів — добові й тижневі стелі на гравця, пару, рівень і тип подарунка, поведінка на межі та порядок ручного підвищення.
- Документація інтеграції — контракти ігрових сервісів і адмін-панелі: які події приходять, яка відповідь вважається успішною, що робити за відсутності відповіді.
- Регламент підтримки — покрокові сценарії: знайти операцію за ідентифікатором, відрізнити нарахування від дубля, відкотити помилковий подарунок, сформулювати відповідь гравцю.
- Регламент розбору спірних операцій — рівні ескалації, строки відповіді, склад доказів (знімок балансу, журнал статусів) і порядок компенсації.
- Інструкції з експлуатації — метрики доставки подарунків, пороги оповіщень, увімкнення «стоп-крана» на нарахування й передача чергування.
Перевірка проста: інженер, який не брав участі в розробці, за цими документами відтворює нарахування й закриває звернення. Що такої перевірки не проходить — доводимо до передачі.
Кейс: зростання відправлень без зростання навантаження на сервери
До переробки подарунок ішов у чергу асинхронно, і результат відправлення ніде не фіксувався окремим станом.
У пікові години — масові події, вечірні вікна — частка невдалих відправлень сягала кількох відсотків, а користувач бачив або «подарунок не відправлено», або, що гірше, відправляв повторно.
Підтримка отримувала сотні звернень на місяць, і кожне розбиралося вручну: за логами застосунку й записами в базі потрібно було зрозуміти, чи списався предмет і чи дійшов він до отримувача. На розбір однієї спірної операції йшло більше півгодини.
Ключова зміна — модель стану операції. На кожне відправлення формується ключ, за яким повторний запит не створює другий запис, а лише повертає поточний статус: створено, зарезервовано, доставлено, повернено.
Списання й нарахування йдуть в одній транзакції по обох сторонах, тому «подарунок пішов, а предмет не списався» перестало бути можливим класом відмови.
Окремо додали ліміти на відправника й отримувача та чергу з наростаючою паузою між повторами — сервер перестав отримувати шквал однакових запитів у момент піку.
Що показали метрики
| Показник | До | Після |
|---|---|---|
| Частка невдалих відправлень | кілька відсотків у пікові години | частки відсотка, залишок — з автоматичним поверненням |
| Звернення в підтримку щодо подарунків | сотні на місяць | у рази менше, спірні випадки закриваються без оператора |
| Розбір спірної операції | більше 30 хвилин вручну | 1-2 хвилини за журналом операцій |
| Пікове навантаження | деградація при триразовому зростанні | чотириразове зростання без додавання вузлів |
Стійкість на піках забезпечується не запасом заліза, а тим, що черга розбирається пачками і пріоритет віддається операціям з уже зарезервованим предметом.
Метрики знімали в Grafana за панелями на частку помилок, глибину черги й час відповіді — той самий набір дашбордів передали команді замовника, щоб відхилення ловилися до звернень користувачів.
Для гравця різниця зводиться до одного: подарунок або доходить, або предмет залишається в нього. Для команди — до передбачуваного розбору інцидентів замість ручних звірок у дні великих подій.
Чим подарунок відрізняється від внутрішньоігрової валюти?
Внутрішньоігрова валюта й подарунок по-різному влаштовані в обліку. Валюта — це число на балансі: сервер змінює його однією операцією, а історія залишається в журналі для звірки.
Подарунок — не число, а факт передачі конкретного предмета конкретному гравцю, тому облік подарунка будується як запис з унікальним ідентифікатором, відправником, отримувачем і часом видачі.
Звідси різна оборотність операції. Помилкове нарахування валюти закривається компенсаційною проводкою: баланс повертається до попереднього значення, запис у журналі залишається. Подарунок після видачі так не відкотити — предмет уже в отримувача.
Платіжні правила App Store вимагають відновлювати куплену валюту при збої, а подарунок відновленню не підлягає: його або видали, або ні. Тому правило повернення задають заздалегідь — до видачі подарунок повертається відправнику, після видачі ні.
Правила лімітів теж розв'язують різні задачі. Для валюти обмежують емісію та швидкість нарахування на акаунт — так стримують інфляцію й шахрайські нарахування.
Для подарунків ліміти рахують за парами відправник-отримувач, за частотою й за цінністю предмета, інакше цінність ганяють по колу між пов'язаними акаунтами.
Економіка предметів залежить від цього напряму. Нарахування валюти збільшує загальну масу й знецінює накопичення, а подарунок лише перерозподіляє вже наявний тираж — але за необмеженої передачі предмети концентруються в перекупників. Тому для подарунків задають стелю цінності й заборону на вторинну передачу.
Технічні сумніви: ліміти, затримки, захист від накрутки
Сумніви щодо подарунків зазвичай одні й ті самі: дублі при повторному відправленні, затримки на поганій мережі, добові ліміти, свіжі акаунти й повідомлення. Нижче — як ці місця закриті в архітектурі.
Гравець натиснув «відправити» двічі — подарунок піде двічі?
Ні. Кожне відправлення отримує унікальний ключ операції, і повтор із тим самим ключем сервер відкидає. Списання з балансу проходить один раз, навіть якщо запити прийшли одночасно з двох пристроїв.
Подарунок загубиться, якщо зв'язок обірветься?
Ні: подарунок фіксується на сервері до відповіді клієнту, а нарахування йде через чергу повторів. Гравець бачить статус «в обробці», і після відновлення зв'язку операція доводиться до кінця.
Як рахуються добові ліміти на відправлення?
Сервер веде лічильники за ковзним вікном, а не за календарною добою: окремо на кількість подарунків одному отримувачу, на загальний обсяг за день і на нові акаунти. При досягненні ліміту гравець бачить причину й час до скидання.
Як закрито накрутку з нових акаунтів?
Свіжі акаунти працюють в обмеженому режимі, поки не наберуть історію: подарунки доступні після прив'язки, а ланцюжки обміну між пов'язаними акаунтами йдуть на ручну перевірку за журналом подій.
Що з повідомленнями та спірними операціями?
Повідомлення йде після підтвердження зарахування, а не в момент відправлення, тому хибних пушів немає. Якщо подарунок не доставлено, спрацьовує повернення за таймаутом, а спір розбирається за журналом: видно ініціатора, ключ операції та всі повтори.
Обговорімо задачу: що надіслати і що отримаєте у відповідь
Обговорення задачі із системою подарунків не повинно розтягуватися на тижні листування: достатньо надіслати набір вступних за проєктом — за ними ми одразу бачимо вузькі місця й не перепитуємо очевидне. Чим конкретніші дані, тим точніша оцінка етапів і менше припущень у плані робіт.
- Як влаштований подарунок у поточній моделі: запис в інвентарі, окрема сутність зі строком життя або посилання на каталог, і що вважається «доставленим».
- Де рахуються ліміти — на клієнті, на ігровому сервері або в окремому сервісі подарунків, і що відбувається при спробі перевищити добовий або загальний ліміт.
- Схема нарахувань і списань: атомарність парних операцій, ідемпотентність повторних запитів, поведінка при обриві зв'язку на середині обміну.
- Як влаштовані повідомлення про подарунок: хто ініціює відправлення, чи є групування при віялі подій, що бачить гравець, який повернувся в гру через добу.
- Поточні метрики: частка доставлених подарунків, повторні спроби, звернення в підтримку з формулюванням «подарунок не прийшов».
- Обмеження майданчиків і правил магазинів до внутрішньоігрових покупок, залежність від платіжного провайдера та його лімітів.
- Хто з боку замовника ухвалює рішення щодо ігрового балансу й тримає тестові акаунти для перевірки сценаріїв.
У відповідь ви отримаєте схему рішення з межами сервісів, план робіт за етапами, порядок введення в бій і перелік ризиків із тим, як кожен із них закривається.







