한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Анатомия игровых лагов › L9 Процесс игрового сервера

Дедлок Deadlock

ID причины sp-deadlock · Основной ответственный Команда разработки · Разработка сервера

Открыть карточку в основной версии с иллюстрациями и экспериментами →

Если два потока ждут блокировки, захваченные друг другом, они встают навсегда.

Почему Поток A держит блокировку 1 и ждёт блокировку 2, а поток B держит блокировку 2 и ждёт блокировку 1 → Следствие Оба встают навсегда, а за ними цепочкой встают и связанные потоки → На экране Весь сервер стоит, watchdog его перезапускает, у всех дисконнект

Симптомы
Фриз, Дисконнект
Факторы
Остановка
У кого
Весь сервер, Только одна функция
Когда
Изредка, случайно, При наплыве игроков
Ответственные
Основной ответственный Команда разработки · Разработка сервера
Команда разработки: задачи
Ввести правило порядка захвата блокировок, использовать блокировки с таймаутом, поставить watchdog и сохранять дамп потоков в момент зависания.
На графике
Массовый обрыв соединений · число подключений, исходящий трафик сервера
Где смотреть
Пока сервер стоит, снять стеки вызовов всех потоков. Для JVM jstack (сам находит и показывает дедлоки), для .NET dotnet-stack, для нативного сервера thread apply all bt в gdb, либо снять core-файл через gcore и разобрать его после перезапуска
Подтверждает
Два или больше потоков стоят со стеками, в которых каждый ждёт блокировку, захваченную другим, а загрузка CPU процессом всё это время близка к 0
Опровергает
Если во время зависания один поток крутится на 100% CPU, это бесконечный цикл. Если потоки ждут ответа БД или внешних сервисов, дело в синхронных вызовах или исчерпании пула потоков
Чем проверить
Инструменты инфраструктуры (игровой код не нужен)

Источники

  1. Runtime locking correctness validator Linux kernel
    Если две блокировки захватываются в противоположном порядке, возникает циклическое ожидание и дедлок (lock inversion deadlock). Ядро Linux проверяет порядок захвата блокировок и предупреждает заранее
  2. Liveness, Readiness, and Startup Probes Kubernetes
    Дедлок, при котором приложение работает, но не может продвинуться, ловят liveness-проверкой и перезапускают контейнер
  3. Diagnostic Tools (Java SE 21 Troubleshooting Guide) Oracle
    jstack выводит стеки всех потоков работающей JVM, а также находит и показывает дедлоки (Found one Java-level deadlock)
  4. dotnet-stack diagnostic tool - .NET CLI Microsoft
    Снимает и выводит управляемые стеки всех потоков процесса .NET
  5. Threads (Debugging with GDB) GNU Project
    thread apply all выполняет одну команду для всех потоков (bt: вывод стека вызовов)
  6. gcore(1) — Linux manual page gdb
    Создаёт core-файл работающей программы, и после этого программа продолжает работать

Смотрите также

Тот же слой: L9 Процесс игрового сервера

Причины с тем же симптомом (Фриз) на других слоях

Карточка в основной версии с иллюстрациями и экспериментами