Quando duas threads esperam, cada uma, o lock que a outra segura, as duas ficam paradas para sempre.
Por quê A thread A segura o lock 1 e espera o lock 2; a B segura o lock 2 e espera o lock 1 → Efeito As duas param para sempre, e as threads relacionadas vão parando em cadeia → Na tela O servidor inteiro para, e o watchdog o reinicia: desconexão de todos
Aleatoriamente, de vez em quando, Quando junta muita gente
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Definir uma regra de ordem para os locks, usar locks com timeout, ter um watchdog e gravar um thread dump no momento da parada.
No gráfico
Queda de conexões em massa · Conexões, volume enviado pelo servidor
Onde olhar
Capturar as pilhas de chamadas de todas as threads durante a parada. Na JVM, jstack (detecta e mostra deadlocks automaticamente); no .NET, dotnet-stack; em servidores nativos, thread apply all bt no gdb, ou gerar um core file com gcore, reiniciar e analisar depois
Confirma se
Duas ou mais threads estão paradas em pilhas que esperam o lock que a outra segura, e enquanto isso o uso de CPU do processo fica perto de 0
Descarta se
Uma thread rodando a 100% de CPU durante a parada: loop infinito. Threads esperando resposta do BD ou de serviços externos: aponta para chamadas síncronas ou esgotamento do pool de threads
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Fontes
Runtime locking correctness validatorLinux kernel Pegar dois locks em ordem inversa causa espera circular e deadlock (lock inversion deadlock); o kernel Linux verifica a ordem dos locks e avisa antes