Solucionando Problemas de Desempenho Lento: Usando 'netstat' e 'ss' de Forma Eficaz

Domine as ferramentas essenciais de rede Linux `netstat` e `ss` para solucionar problemas de desempenho de forma eficiente. Este guia compara o legado `netstat` com o utilitário moderno e mais rápido `ss`, fornecendo exemplos práticos de comandos. Aprenda a filtrar resultados por estado de conexão, identificar serviços em escuta e diagnosticar gargalos de rede rapidamente usando estatísticas de socket Netlink.

Solucionando Problemas de Desempenho Lento: Usando 'netstat' e 'ss' de Forma Eficaz

Quando um serviço Linux parece lento, a tabela de sockets é um dos lugares mais rápidos para separar "o aplicativo está sobrecarregado" de "o caminho de rede está bagunçado". Um servidor web que não consegue aceitar novas conexões, um worker que está travado ao abrir sessões de banco de dados e um host com uma pilha de handshakes TCP meio abertos parecem uma lentidão vaga para a pessoa esperando do outro lado.

netstat e ss ajudam você a responder uma pergunta mais específica: quais sockets de rede existem nesta máquina agora, em que estado eles estão e qual processo os possui? netstat ainda é útil em sistemas mais antigos e em runbooks antigos. ss é a ferramenta que eu uso primeiro em Linux moderno porque é mais rápida em hosts ocupados e tem filtros integrados melhores.

Por que Monitorar Sockets de Rede?

Latência de rede e lentidão estão frequentemente ligadas a problemas de conexão, em vez de exaustão de CPU ou memória. Monitorar sockets ajuda administradores a responder perguntas críticas como:

  • Quais portas estão ativamente ouvindo por conexões?
  • Há muitas conexões presas nos estados SYN_RECV ou TIME_WAIT?
  • Qual processo (PID) está usando uma porta específica?
  • Há conexões de saída inesperadas ocorrendo?

Ao examinar as estatísticas de socket, você pode rapidamente descartar problemas de configuração de rede ou identificar contenção de recursos relacionada ao tratamento de conexões.

A Ferramenta Legada: netstat

netstat tem sido o utilitário padrão para exibir conexões de rede, tabelas de roteamento, estatísticas de interface e conexões de mascaramento por décadas. Embora tenha sido substituído pelo ss em muitos sistemas modernos, ele ainda está amplamente disponível e é frequentemente familiar para administradores de longa data.

Exemplos Comuns de netstat

As flags mais comuns usadas com netstat fornecem uma visão geral abrangente:

Flag Descrição
-a Mostra todos os sockets (ouvindo e não ouvindo)
-n Mostra endereços numéricos em vez de tentar resolver nomes de host e serviços (acelera a saída)
-t Mostra conexões TCP
-u Mostra conexões UDP
-l Mostra apenas sockets em escuta
-p Mostra o PID/Nome do programa associado ao socket (requer privilégios de root)

Exemplo: Visualizando todas as conexões TCP ativas numericamente

sudo netstat -ant

Exemplo: Encontrando o que está ouvindo na porta 80 (HTTP)

sudo netstat -tulpen | grep ':80'

Entendendo os Estados da Conexão (netstat)

A saída do netstat geralmente inclui uma coluna State. Os principais estados a serem observados incluem:

  • LISTEN: Aguardando conexões de entrada.
  • ESTABLISHED: Uma conexão ativa e aberta.
  • TIME_WAIT: Um socket aguardando por um curto período após o fechamento para garantir que pacotes atrasados sejam tratados.
  • SYN_RECV: Aguardando a confirmação final de um handshake de três vias (pode indicar um ataque de inundação SYN se excessivo).

Aviso sobre netstat: netstat muitas vezes depende da análise dos arquivos /proc/net/*, o que pode ser lento, especialmente em sistemas com um volume muito alto de conexões ativas (milhares). Esta é a principal razão pela qual o ss foi desenvolvido.

O Substituto Moderno: ss (Estatísticas de Socket)

O utilitário ss é significativamente mais rápido que o netstat porque recupera informações de socket diretamente do espaço do kernel usando sockets Netlink, ignorando consultas mais lentas ao sistema de arquivos.

Exemplos Comuns de ss

A estrutura de flags para ss é muito semelhante à do netstat, promovendo uma transição fácil:

Flag Descrição
-a Mostra todos os sockets
-n Mostra endereços numéricos
-t Mostra sockets TCP
-u Mostra sockets UDP
-l Mostra sockets em escuta
-p Mostra informações do processo (PID/Programa)

Exemplo: Visualizando todas as conexões TCP ativas numericamente (Equivalente a netstat -ant)

ss -ant

Exemplo: Encontrando o que está ouvindo na porta 443 (HTTPS)

sudo ss -tulpen | grep ':443'

Filtragem Avançada com ss

Uma das maiores vantagens do ss é sua capacidade de realizar filtragem direta em estados de conexão, o que é muito mais eficiente do que canalizar a saída do netstat para o grep.

Filtrando por Estado da Conexão

Você pode usar a opção state diretamente no comando ss. Isso é extremamente útil para diagnosticar acúmulo de conexões.

Encontrando todos os sockets atualmente no estado TIME-WAIT:

ss -tan state time-wait

Encontrando todos os sockets no estado SYN-SENT (lado do cliente aguardando resposta do servidor):

ss -tan state syn-sent

Filtrando por Porta ou Endereço

A filtragem por endereço/porta de destino ou origem é direta:

Mostrar conexões estabelecidas destinadas à porta 22 (SSH):

ss -tn state established '( dport = :22 or sport = :22 )'

Mostrar conexões relacionadas a um endereço IP local específico:

ss -ant '( daddr = 192.168.1.100 or saddr = 192.168.1.100 )'

Análise de Desempenho: Comparação netstat vs. ss

Ao solucionar problemas, a escolha entre as ferramentas muitas vezes se resume à velocidade e ao detalhe.

Característica netstat ss
Velocidade Mais lento (Lê arquivos) Muito mais rápido (Usa sockets Netlink)
Sintaxe Madura, bem documentada Flags semelhantes, opções específicas mais novas
Filtragem Requer canalização para grep Suporte nativo a estado e filtragem de endereço
Profundidade da Informação Bom para o básico Mais detalhes sobre tamanhos de buffer de socket (Informações TCP)
Disponibilidade Quase universal Padrão em distribuições Linux modernas

Diagnosticando Estabelecimento Lento de Conexão

Se os clientes relatarem conexões lentas, verifique se há sockets presos aguardando handshakes. Usar ss é a maneira mais rápida de determinar isso:

  1. Verifique contagens altas de SYN-RECV: Isso sugere que o servidor está recebendo solicitações de conexão, mas não completando o handshake, muitas vezes devido a exaustão de recursos ou alta carga de tráfego.
    ss -s | grep syn-rec
    
  2. Verifique contagens altas de SYN-SENT: Se o próprio servidor está iniciando muitas conexões (por exemplo, atuando como cliente para bancos de dados ou outras APIs), isso mostra que ele está aguardando respostas.
    ss -s | grep syn-sent
    

Se você observar números altos sustentados em qualquer categoria, trate-os como uma pista, não como um veredito. SYN-SENT pode significar que um host remoto está inativo, uma rota está errada, um firewall está descartando tráfego silenciosamente ou o serviço remoto está sobrecarregado. SYN-RECV pode significar que o servidor está sob carga, pacotes estão sendo perdidos ou clientes estão abrindo conexões e não as completando.

Um Fluxo de Triagem Prático

Quando alguém diz "o aplicativo está lento", geralmente começo com uma passagem curta e repetível:

sudo ss -tulpen
ss -s
sudo ss -tan state established '( sport = :443 or dport = :443 )' | head
sudo ss -tan state syn-recv
sudo ss -tan state time-wait | head

O primeiro comando confirma que o serviço esperado está realmente ouvindo e mostra o processo proprietário. O resumo mostra se o host tem um número surpreendente de sockets TCP. O comando de estabelecidos filtrados prova se o tráfego real do cliente está anexado à porta. As verificações syn-recv e time-wait mostram se a configuração da conexão ou a rotatividade de conexões merecem atenção.

Por exemplo, imagine um proxy reverso Nginx onde os usuários reclamam que novas requisições travam por alguns segundos. sudo ss -tulpen | grep ':443' confirma que o Nginx possui o listener HTTPS. ss -s mostra um grande total de TCP, e sudo ss -tan state syn-recv '( sport = :443 )' continua retornando linhas dos mesmos intervalos de origem. Isso não prova automaticamente um ataque, mas diz para você olhar as verificações de integridade do balanceador de carga, perda de pacotes upstream, pressão no backlog SYN, logs de firewall e possivelmente limites de taxa.

Agora imagine o mesmo proxy com muito poucos sockets SYN_RECV, mas muitas conexões estabelecidas com um banco de dados upstream na porta 5432. Isso aponta você para longe do HTTPS público e em direção ao caminho do banco de dados:

sudo ss -tanp '( dport = :5432 or sport = :5432 )'

Se o processo proprietário é seu aplicativo e a contagem continua subindo, a próxima pergunta útil é se o aplicativo está vazando conexões, aguardando consultas lentas ou falhando em retornar conexões a um pool. ss não responde a essa pergunta de nível de aplicativo, mas leva você à sala certa.

Lendo TIME_WAIT Sem Entrar em Pânico

TIME_WAIT é um estado TCP normal, não um erro por si só. Um servidor que lida com muitas conexões de curta duração naturalmente mostrará sockets TIME_WAIT. Eles existem para que pacotes atrasados de uma conexão antiga não sejam confundidos com uma nova.

A questão útil é se TIME_WAIT corresponde à carga de trabalho. Um job em lote que abre uma nova conexão HTTP para cada pequena requisição pode criar uma onda de TIME_WAIT. Um serviço que deveria usar keep-alive, mas não o faz, pode fazer o mesmo. Antes de ajustar as configurações do kernel, verifique se o aplicativo pode reutilizar conexões, habilitar HTTP keep-alive ou usar um pool de clientes adequado.

Tenha cuidado com conselhos antigos que sugerem alterar cegamente os sysctls TCP para "corrigir" TIME_WAIT. Algumas configurações dependem da versão do kernel, algumas foram removidas ou desencorajadas ao longo do tempo, e algumas criam falhas sutis por trás de NAT ou balanceadores de carga. Comece entendendo por que as conexões são de curta duração.

Verificando Pressão Local Versus Remota

Um detalhe que economiza tempo é se o host local está principalmente aceitando conexões ou principalmente fazendo-as. Um proxy de frontend geralmente tem muitas conexões onde a porta local é 80 ou 443. Um servidor de aplicativos que se comunica com bancos de dados e APIs pode ter muitas conexões onde a porta remota é 5432, 3306, 6379 ou 443.

Para listeners locais e tráfego de entrada:

sudo ss -tan '( sport = :443 )'

Para tráfego de saída para uma dependência:

sudo ss -tan '( dport = :6379 )'

Essa distinção muda a próxima conversa. Se o HTTPS de entrada está se acumulando, você pode precisar inspecionar o balanceador de carga, a terminação TLS, os limites do worker ou o comportamento do cliente. Se as conexões Redis de saída estão se acumulando, o aplicativo local pode estar criando muitas conexões de cliente, aguardando no Redis ou tentando novamente de forma muito agressiva.

Quando você precisa de uma contagem rápida sem ler centenas de linhas, combine ss com ferramentas simples de shell:

sudo ss -tan state established '( dport = :443 )' | wc -l
sudo ss -tan state established '( dport = :5432 )' | wc -l

A contagem inclui a linha de cabeçalho, então não é uma métrica perfeita. Para triagem, ainda é útil. Se o número dobra a cada minuto durante um incidente, você tem um sinal mais forte do que uma única captura instantânea.

Contêineres e Namespaces de Rede

Em hosts conteinerizados, tenha cuidado sobre onde você executa o comando. Executar ss no host mostra os namespaces de rede do host e as portas publicadas, mas pode não mostrar a mesma visão que o processo vê dentro de seu contêiner. Se um serviço é executado em um contêiner, compare ambas as visões:

sudo ss -tulpen
docker exec <container> ss -tulpen

Para Kubernetes, use a visão do nó para listeners de nível de host e kubectl exec para o namespace de rede do pod. Uma porta pode estar aberta dentro do contêiner enquanto o host, serviço, ingress ou política de rede ainda impede que o tráfego a alcance. ss é uma ferramenta de verdade local, não um teste de conectividade de ponta a ponta.

Melhores Práticas para Solução de Problemas de Rede

  1. Sempre Use -n: Ao solucionar problemas de desempenho ou criar scripts, use a flag numérica (-n) para evitar atrasos de resolução de DNS, que podem tornar os diagnósticos lentos.
  2. Priorize ss: Adote ss como sua ferramenta padrão. Reserve netstat apenas para sistemas legados onde ss não está disponível.
  3. Execute como Root para PID: Para ver qual programa está usando uma porta, você geralmente precisa de privilégios sudo ou root ao usar a flag -p com ambos os utilitários.
  4. Verifique Estatísticas de Interface: Não se esqueça dos contadores de interface. Use ip -s link show <nome_da_interface> para verificar pacotes descartados ou erros, que podem indicar um problema de camada física em vez de um problema de socket.
  5. Compare capturas instantâneas. Uma saída de ss é uma fotografia. Duas saídas tiradas com um minuto de diferença dizem se a situação está crescendo, diminuindo ou estável.
  6. Anote o filtro exato. Durante incidentes, um comando salvo como ss -tan '( dport = :5432 )' é mais fácil de repetir e comparar do que um pipeline grep lembrado pela metade.

O hábito que compensa é simples: comece com listeners, vá para estados de conexão, identifique o processo proprietário e então decida se o próximo passo pertence ao aplicativo, ao caminho de rede, ao firewall ou ao kernel.