Retransmissão espúria por pico de latência Spurious RTO from delay spikes
ID da causa rt-spurious-delay · Responsável principal Externo (Externo) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura), Desenvolvimento do cliente (Equipe de desenvolvimento)
O pacote só chegou muito atrasado por um instante, sem se perder. Mesmo assim, se o atraso passa do RTO, quem envia considera o pacote perdido e retransmite.
Por quê Bufferbloat, economia de energia do Wi-Fi, transição de estado do rádio móvel ou pausa da máquina virtual levam a latência momentânea a centenas de ms → Efeito O RTO expira primeiro e o pacote é retransmitido, e o original chega logo depois (quem recebe fica com uma cópia duplicada) → Na tela Travamento e avanço rápido vêm do próprio pico de latência. A retransmissão espúria quase não aumenta o travamento; só faz subir a métrica de retransmissão e acaba sendo confundida com perda
Aleatoriamente, de vez em quando, Depois de ficar parado
Responsável
Responsável principal Externo (Externo) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura), Desenvolvimento do cliente (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
No cliente Android 10 ou superior, pedir o modo Wi-Fi de baixa latência durante o jogo (Wi-Fi lock WIFI_MODE_FULL_LOW_LATENCY, que só vale com a tela ligada e o jogo em primeiro plano), para reduzir os picos de latência causados pela economia de energia.
O que fazer (Equipe de infraestrutura)
Evitar instâncias do tipo burstable, não baixar demais o RTO mínimo, manter F-RTO e timestamps (tcp_frto, tcp_timestamps), ler as métricas de retransmissão junto com TCPSpuriousRTOs e TCPDSACKRecv do nstat para não confundi-las com perda.
O que fazer (Externo)
Orientar os jogadores a usar SQM no roteador e desligar a economia de energia do Wi-Fi, para reduzir os próprios picos de latência.
Números de referência
O Linux detecta RTOs espúrios com F-RTO e pode desfazer a redução da taxa de envio. Confira pelo TCPSpuriousRTOs do nstat (vezes em que um RTO foi considerado espúrio) e pelo TCPDSACKRecv (vezes em que quem recebe avisou que “já tinha recebido”).
No gráfico
Picos aleatórios · RTT (ping), RTOs espúrios
Onde olhar
Rodar o nstat a cada 1 minuto e ver juntos os incrementos de TcpExtTCPTimeouts (expirações do RTO), TcpExtTCPSpuriousRTOs, TcpExtTCPDSACKRecv e TcpExtTCPLostRetransmit. Com captura de pacotes, usar o filtro do Wireshark tcp.analysis.spurious_retransmission
Confirma se
Quando os RTOs aumentam, TcpExtTCPSpuriousRTOs ou TcpExtTCPDSACKRecv sobem junto, e no mesmo momento o RTT dispara para centenas de ms. Na captura do lado que recebe, chegaram tanto o original quanto a retransmissão
Descarta se
TcpExtTCPSpuriousRTOs e DSACK parados, mas TcpExtTCPLostRetransmit (perda até do que foi reenviado) aumentando: perda real. RTT sem picos, mas DSACK alto de forma constante: “Retransmissão rápida espúria por pacotes fora de ordem”
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
SNMP counterLinux kernel TcpExtTCPSpuriousRTOs (RTOs espúrios detectados pelo F-RTO), TcpExtTCPDSACKRecv (DSACKs recebidos), TcpExtTCPLostRetransmit (vezes em que o SACK indicou que um pacote reenviado se perdeu de novo)
IP SysctlLinux kernel tcp_frto ligado por padrão (bom para redes sem fio com RTT instável), tcp_timestamps com padrão 1
WifiManagerAndroid (Google) WIFI_MODE_FULL_LOW_LATENCY (API 29, Android 10): Wi-Fi lock de baixa latência que só vale com conexão a um AP, tela ligada e app em primeiro plano
net/ipv4/proc.cLinux kernel Nomes dos contadores no nstat: TCPTimeouts, TCPSpuriousRTOs, TCPDSACKRecv, TCPLostRetransmit
net/ipv4/tcp_timer.cLinux kernel TCPTimeouts aumenta quando o timer de retransmissão (RTO) expira