Стоимость минуты простоя в 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 помогает не просто анализировать, а улучшать процессы.

  • Главное — не просто «фиксить баг», а менять условия, при которых он стал возможен.

Комментарии (0)