Quando todas as worker threads que processam tarefas ficam presas em trabalhos lentos, os pedidos novos ficam esperando indefinidamente.
Por quê As worker threads ficam presas esperando resposta de APIs externas ou do BD → Efeito Não há thread livre para os pedidos novos → Na tela Loading infinito em recursos específicos, como login ou loja
Quando junta muita gente, Logo após login ou manutenção
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Pôr timeout nas chamadas lentas, separar pools de threads por recurso, tornar as chamadas assíncronas.
No gráfico
Achata ao bater no limite · Threads e tamanho da fila do pool de threads, tempo de processamento dos pedidos
Onde olhar
No .NET, ver o número de threads e o tamanho da fila do pool de threads no dotnet-counters monitor (dotnet.thread_pool.thread.count e dotnet.thread_pool.queue.length a partir do .NET 9, ThreadPool Thread Count e ThreadPool Queue Length até o 8) e conferir com dotnet-stack onde as worker threads estão esperando. Em servidores JVM ou nativos, conferir o mesmo com thread dumps
Confirma se
O uso de CPU fica bem abaixo de 100%, mas o número de threads sobe devagar sem parar ou fica colado no teto, a fila acumula e a maioria dos workers espera a resposta da mesma chamada externa (BD, HTTP)
Descarta se
Fila vazia e mesmo assim lento: o próprio destino das chamadas está lento, então aponta para falha em cascata ou dependência de serviços externos
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
Se o recebimento de pacotes e a lógica do jogo dividem o mesmo pool de worker threads, basta algumas tarefas lentas ocuparem todos os workers para o processamento de pacotes do servidor inteiro parar.
Debug ThreadPool StarvationMicrosoft Quando não sobra thread no pool e as tarefas novas esperam, a resposta fica lenta; a causa é código bloqueante que segura threads. No dotnet-counters, CPU bem abaixo de 100% com dotnet.thread_pool.thread.count subindo devagar sem parar é sinal de esgotamento (muitas vezes dotnet.thread_pool.queue.length também está alto); dotnet-stack mostra onde as threads esperam
Avoiding insurmountable queue backlogsAWS Concorrência = taxa de chegada × latência (lei de Little). Com 100 pedidos por segundo, se a latência sobe de 100 ms para 10 s, as threads necessárias passam de 10 para 1.000 e o pool se esgota
Bulkhead PatternMicrosoft Azure Com um pool de conexões e de threads separado para cada destino, a falha de um destino bloqueia só aquele pool
.NET runtime metrics.NET dotnet.thread_pool.thread.count (threads do pool) e dotnet.thread_pool.queue.length (tarefas na fila) existem a partir do .NET 9
Well-known EventCounters in .NETMicrosoft ThreadPool Thread Count (threadpool-thread-count) e ThreadPool Queue Length (threadpool-queue-length) do .NET 8 e anteriores