Стоимость минуты простоя в iGaming может приводить к миллионам упущенной прибыли и более тяжелым репутационным потерям. Когда real-time ставки замирают, а букмекерские терминалы уходят в ступор - это не просто баг. Это экзамен на зрелость команды и процессов. Что мы делаем после - определяет, повторится ли он снова.

Пролог: инцидент в iGaming
iGaming-платформа "OneBet" только что выкатала обновление SignalR-сервиса. Этот сервис отвечает за real-time каналы:
live‑ставки на сайте,
матч‑трекеры,
трансляции коэффициентов в букмекерские офисы.
Через 6 часов после релиза:
real‑time данные отваливаются каждые 3–5 минут,
на сайте — зависание матчей,
в терминалах клубов — недоступные экраны ставок,
техподдержка завалена тикетами,
VIP‑клиенты жалуются.
Первые действия: перезапуск сервиса по крону каждые 10 минут. Симптомы уходят на 7 минут, потом всё по новой.
Менеджмент требует отчёт. Команда - в панике. Первое, что делают - обвиняют релиз. И пишут отчёт в духе "проблема с новой версией, всё сломалось". Только это - не отчёт. Это эмоции.
Почему отчёты "на коленке" не работают
Просто перечислить "что произошло" - недостаточно.
Нужно докопаться до корневой причины, а не остановиться на симптоме.
Один из самых простых и действенных инструментов - техника 5 Why.
Задавай "почему?" не один, а пять раз - и каждый раз глубже, чтобы добраться до системной причины, а не тушить очередной пожар.
Пример:
❓ Почему real-time замирает на проде?
→ Потому что SignalR-сервис уходит в OOM.❓ Почему возникает OOM?
→ Потому что память заполняется неосвобождёнными WebSocket-сессиями.❓ Почему сессии не очищаются?
→ Потому что не срабатываетOnDisconnectedAsync
.❓ Почему этот обработчик перестал работать?
→ Потому что в новой версии поменяли логику соединений.❓ Почему это не было замечено до релиза?
→ Потому что на такие изменения не было тестов и они не попали в код-ревью.
И только на пятом "почему" становится видно: проблема не в коде, а в процессе, в котором real-time изменения попадают в прод без надлежащей проверки.
Как подойти системно: DMAIC
Используем проверенный фреймворк из Six Sigma - DMAIC:
1. Define (Определить)
Проблема:
После релиза SignalR-сервиса происходит утечка памяти и, как следствие, падение real-time функциональности на проде.
Бизнес-эффект:
Потери ставок в live-режиме
50+ недоступных офисов (касс)
Ущерб репутации в high-stakes сегменте
2. Measure (Измерить)
Время до деградации: ~18 минут
Рост памяти: с 400 МБ до 12+ ГБ
Обращений в поддержку : 134 за сутки
Кол-во пострадавших стран: 3
Время стабилизации: 2.5 дня
3. Analyze (Анализировать)
Использованные инструменты:
DotMemory: утечка в
HubConnectionContext
Kibana Logs: резкий рост подключений
-
5 Whys:
Почему падает? Out of Memory
Почему? WebSocket-сессии не освобождаются
Почему?
OnDisconnectedAsync
не отрабатываетПочему? Изменена логика, не покрытая тестами
Почему? В релиз пошло срочное изменение без ревью
4. Improve (Улучшить)
Добавлена очистка при дисконнекте
Написан unit-тест на
HubConnectionTracker
Внедрён memory snapshot на pre-prod
Добавлен чеклист: любые real-time изменения требуют нагрузочного теста
5. Control (Контроль)
Мониторинг утечек и графики памяти по умолчанию
SignalR-service вынесен в отдельный релизный поток
Пост-инцидент отчёты стали обязательными
Регламент дополнен требованием к real-time покрытию
А можно было предвидеть? Да! Через FMEA
Перед релизом можно (и нужно) проводить анализ рисков FMEA (Failure Mode and Effects Analysis):
Failure Mode |
Причина |
S |
O |
D |
RPN |
---|---|---|---|---|---|
Утечка памяти в SignalR |
Неочищенные WebSocket |
9 |
6 |
7 |
378 |
Сбой терминалов в офисах |
Нет stage-тестирования в live-нагрузке |
8 |
5 |
6 |
240 |
Отсутствие rollback-механизма |
Нет автоматизированного отката |
7 |
5 |
5 |
175 |
Как читать:
-
Первый риск - утечка памяти:
Очень опасный (9),
Вполне вероятный (6),
Трудно обнаружить заранее (7).
RPN = 378 - красная зона. Это блокер, с ним надо работать до релиза.
-
Второй риск - отсутствие stage-нагрузки:
Тоже серьёзный, но менее вероятный.
-
Третий риск - откат:
Возможен, но более контролируемый.
Сценарий с RPN = 378 - явный блокер релиза. Его можно было найти заранее - при наличии культуры FMEA.
Мозговой штурм: Fishbone Diagram
Проблема: сервис уходит в OOM
Причины:
Люди - срочная задача сделана, без code review
Процессы - real-time фичи тестируются как обычные
Технологии - нет CI-профилирования на утечки
Среда - нет stage, схожего с реальным продом
Пример зрелого отчёта об инциденте
## Incident Summary
Date: 2025-07-10
Component: SignalR Real-Time Service
Impact: Real-time channels crashed across web and retail environments
## Root Cause
Unreleased WebSocket sessions caused memory leak and OOM errors. OnDisconnectedAsync handler failed to trigger due to internal refactoring.
## Fixes
- Dispose logic added
- DotMemory test on CI
- Unit coverage for SignalR disconnect flow
## Preventive Actions
- FMEA introduced before real-time changes
- Real-time code review policy
- Monitoring and alerts on memory thresholds
Что помогло в решении:
Инструмент |
Для чего |
---|---|
JetBrains DotMemory |
Анализ дампа и утечки |
Kibana Logs / Grafana Metrics |
Поведение под нагрузкой |
CI/CD |
Добавление memory snapshot'ов |
Confluence шаблон RCA |
Унификация отчётов |
FMEA в Google Sheets |
Анализ рисков перед релизом |
Выводы
Хороший RCA — это не поиск виноватых, а поиск корня проблемы.
Использование фреймворков DMAIC, FMEA, Fishbone помогает не просто анализировать, а улучшать процессы.
Главное — не просто «фиксить баг», а менять условия, при которых он стал возможен.