Risoluzione dei Problemi di Prestazioni Lente: Utilizzare 'netstat' e 'ss' in Modo Efficace
Padroneggia gli strumenti essenziali di rete Linux `netstat` e `ss` per una risoluzione efficiente dei problemi di prestazioni. Questa guida confronta il legacy `netstat` con la moderna e più veloce utility `ss`, fornendo esempi pratici di comandi. Impara a filtrare i risultati per stato della connessione, identificare i servizi in ascolto e diagnosticare rapidamente i colli di bottiglia di rete utilizzando le statistiche dei socket Netlink.
Risoluzione dei Problemi di Prestazioni Lente: Utilizzare 'netstat' e 'ss' in Modo Efficace
Quando un servizio Linux sembra lento, la tabella dei socket è uno dei posti più rapidi per distinguere "l'app è sovraccarica" da "il percorso di rete è disordinato". Un server web che non può accettare nuove connessioni, un worker che rimane bloccato nell'apertura di sessioni di database e un host con un mucchio di handshake TCP semiaperti appaiono tutti come una vaga lentezza alla persona che aspetta dall'altra parte.
netstat e ss ti aiutano a rispondere a una domanda più ristretta: quali socket di rete esistono su questa macchina in questo momento, in quale stato si trovano e quale processo li possiede? netstat è ancora utile su sistemi più vecchi e in vecchi runbook. ss è lo strumento a cui ricorro per primo su Linux moderno perché è più veloce su host occupati e ha filtri integrati migliori.
Perché Monitorare i Socket di Rete?
La latenza di rete e la lentezza sono spesso legate a problemi di connessione piuttosto che all'esaurimento di CPU o memoria. Il monitoraggio dei socket aiuta gli amministratori a rispondere a domande critiche come:
- Quali porte sono attivamente in ascolto per le connessioni?
- Ci sono troppe connessioni bloccate negli stati
SYN_RECVoTIME_WAIT? - Quale processo (PID) sta utilizzando una porta specifica?
- Ci sono connessioni in uscita inaspettate?
Esaminando le statistiche dei socket, puoi rapidamente escludere problemi di configurazione di rete o identificare contese di risorse legate alla gestione delle connessioni.
Lo Strumento Legacy: netstat
netstat è stato per decenni l'utility standard per visualizzare connessioni di rete, tabelle di routing, statistiche di interfaccia e connessioni di masquerading. Sebbene deprecato a favore di ss su molti sistemi moderni, rimane ampiamente disponibile e spesso familiare agli amministratori di lunga data.
Esempi Comuni di netstat
I flag più comuni usati con netstat forniscono una panoramica completa:
| Flag | Descrizione |
|---|---|
-a |
Mostra tutti i socket (in ascolto e non in ascolto) |
-n |
Mostra indirizzi numerici invece di tentare di risolvere nomi host e nomi di servizio (accelera l'output) |
-t |
Mostra connessioni TCP |
-u |
Mostra connessioni UDP |
-l |
Mostra solo i socket in ascolto |
-p |
Mostra il PID/nome del programma associato al socket (richiede privilegi di root) |
Esempio: Visualizzare tutte le connessioni TCP attive in modo numerico
sudo netstat -ant
Esempio: Trovare cosa è in ascolto sulla porta 80 (HTTP)
sudo netstat -tulpen | grep ':80'
Comprendere gli Stati delle Connessioni (netstat)
L'output di netstat include spesso una colonna State. Gli stati chiave da tenere d'occhio includono:
- LISTEN: In attesa di connessioni in arrivo.
- ESTABLISHED: Una connessione attiva e aperta.
- TIME_WAIT: Un socket in attesa per un breve periodo dopo la chiusura per garantire che i pacchetti ritardati vengano gestiti.
- SYN_RECV: In attesa dell'ultimo riconoscimento di un three-way handshake (può indicare un attacco SYN flood se eccessivo).
Avvertenza su
netstat:netstatspesso si basa sull'analisi dei file/proc/net/*, che può essere lenta, specialmente su sistemi con un volume molto elevato di connessioni attive (migliaia). Questo è il motivo principale per cui è stato sviluppatoss.
Il Sostituto Moderno: ss (Statistiche dei Socket)
L'utility ss è significativamente più veloce di netstat perché recupera le informazioni sui socket direttamente dallo spazio del kernel utilizzando i socket Netlink, bypassando le ricerche più lente nel filesystem.
Esempi Comuni di ss
La struttura dei flag per ss è molto simile a netstat, promuovendo una facile transizione:
| Flag | Descrizione |
|---|---|
-a |
Mostra tutti i socket |
-n |
Mostra indirizzi numerici |
-t |
Mostra socket TCP |
-u |
Mostra socket UDP |
-l |
Mostra socket in ascolto |
-p |
Mostra informazioni sul processo (PID/Programma) |
Esempio: Visualizzare tutte le connessioni TCP attive in modo numerico (Equivalente a netstat -ant)
ss -ant
Esempio: Trovare cosa è in ascolto sulla porta 443 (HTTPS)
sudo ss -tulpen | grep ':443'
Filtraggio Avanzato con ss
Uno dei maggiori vantaggi di ss è la sua capacità di eseguire filtraggi diretti sugli stati delle connessioni, che è molto più efficiente che inviare l'output di netstat a grep.
Filtraggio per Stato della Connessione
Puoi usare l'opzione state direttamente all'interno del comando ss. Questo è estremamente utile per diagnosticare l'accumulo di connessioni.
Trovare tutti i socket attualmente nello stato TIME-WAIT:
ss -tan state time-wait
Trovare tutti i socket nello stato SYN-SENT (lato client in attesa della risposta del server):
ss -tan state syn-sent
Filtraggio per Porta o Indirizzo
Filtrare per indirizzo/porta di destinazione o origine è semplice:
Mostra le connessioni stabilite destinate alla porta 22 (SSH):
ss -tn state established '( dport = :22 or sport = :22 )'
Mostra le connessioni relative a uno specifico indirizzo IP locale:
ss -ant '( daddr = 192.168.1.100 or saddr = 192.168.1.100 )'
Analisi delle Prestazioni: Confronto tra netstat e ss
Quando si risolvono i problemi, la scelta tra gli strumenti spesso si riduce alla velocità e ai dettagli.
| Caratteristica | netstat |
ss |
|---|---|---|
| Velocità | Più lento (Legge file) | Molto più veloce (Usa socket Netlink) |
| Sintassi | Matura, ampiamente documentata | Flag simili, nuove opzioni specifiche |
| Filtraggio | Richiede piping a grep |
Supporto nativo per filtraggio stato e indirizzo |
| Profondità Informazioni | Buono per le basi | Più dettagli sulle dimensioni del buffer del socket (Info TCP) |
| Disponibilità | Quasi universale | Standard sulle moderne distribuzioni Linux |
Diagnosticare un'Instaurazione Lenta della Connessione
Se i client segnalano connessioni lente, controlla i socket bloccati in attesa di handshake. Usare ss è il modo più veloce per determinarlo:
- Controlla conteggi elevati di
SYN-RECV: Questo suggerisce che il server sta ricevendo richieste di connessione ma non completa l'handshake, spesso a causa di esaurimento delle risorse o carico di traffico elevato.ss -s | grep syn-rec - Controlla conteggi elevati di
SYN-SENT: Se il server stesso sta avviando molte connessioni (ad esempio, fungendo da client per database o altre API), questo mostra che sta aspettando risposte.ss -s | grep syn-sent
Se vedi numeri elevati sostenuti in una delle due categorie, trattali come un indizio piuttosto che un verdetto. SYN-SENT può significare che un host remoto è giù, una rotta è sbagliata, un firewall sta silenziosamente scartando il traffico o il servizio remoto è sovraccarico. SYN-RECV può significare che il server è sotto carico, i pacchetti vengono persi o i client aprono connessioni e non le completano.
Un Flusso di Triage Pratico
Quando qualcuno dice "l'app è lenta", di solito inizio con un passaggio breve e ripetibile:
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
Il primo comando conferma che il servizio previsto è effettivamente in ascolto e mostra il processo proprietario. Il riepilogo mostra se l'host ha un numero sorprendente di socket TCP. Il comando filtrato per connessioni stabilite prova se il traffico client reale è collegato alla porta. I controlli syn-recv e time-wait mostrano se l'impostazione della connessione o il ricambio di connessione meritano attenzione.
Ad esempio, immagina un proxy inverso Nginx in cui gli utenti si lamentano che le nuove richieste si bloccano per alcuni secondi. sudo ss -tulpen | grep ':443' conferma che Nginx possiede il listener HTTPS. ss -s mostra un grande totale TCP, e sudo ss -tan state syn-recv '( sport = :443 )' continua a restituire righe dagli stessi intervalli di origine. Questo non prova automaticamente un attacco, ma ti dice di guardare i controlli di integrità del bilanciatore di carico, la perdita di pacchetti a monte, la pressione del backlog SYN, i log del firewall e possibilmente i limiti di velocità.
Ora immagina che lo stesso proxy abbia pochissimi socket SYN_RECV ma molte connessioni stabilite verso un database a monte sulla porta 5432. Questo ti allontana dall'HTTPS pubblico e ti indirizza verso il percorso del database:
sudo ss -tanp '( dport = :5432 or sport = :5432 )'
Se il processo proprietario è la tua applicazione e il conteggio continua a salire, la prossima domanda utile è se l'applicazione sta perdendo connessioni, aspettando query lente o non riuscendo a restituire le connessioni a un pool. ss non risponde a quella domanda a livello applicativo, ma ti porta nella stanza giusta.
Leggere TIME_WAIT Senza Farsi Prendere dal Panico
TIME_WAIT è uno stato TCP normale, non un errore di per sé. Un server che gestisce molte connessioni di breve durata mostrerà naturalmente socket TIME_WAIT. Esistono in modo che i pacchetti ritardati di una vecchia connessione non vengano confusi con una nuova.
La domanda utile è se TIME_WAIT corrisponde al carico di lavoro. Un job batch che apre una nuova connessione HTTP per ogni piccola richiesta può creare un'ondata di TIME_WAIT. Un servizio che dovrebbe usare keep-alive ma non lo fa può fare lo stesso. Prima di ottimizzare le impostazioni del kernel, verifica se l'applicazione può riutilizzare le connessioni, abilitare HTTP keep-alive o usare un pool client appropriato.
Fai attenzione ai vecchi consigli che suggeriscono di modificare ciecamente i sysctl TCP per "risolvere" TIME_WAIT. Alcune impostazioni dipendono dalla versione del kernel, alcune sono state rimosse o sconsigliate nel tempo e alcune creano guasti subdoli dietro NAT o bilanciatori di carico. Inizia capendo perché le connessioni sono di breve durata.
Controllare la Pressione Locale vs Remota
Un dettaglio che fa risparmiare tempo è se l'host locale sta principalmente accettando connessioni o principalmente creandole. Un proxy frontend di solito ha molte connessioni in cui la porta locale è 80 o 443. Un server applicativo che parla con database e API può avere molte connessioni in cui la porta remota è 5432, 3306, 6379 o 443.
Per listener locali e traffico in entrata:
sudo ss -tan '( sport = :443 )'
Per traffico in uscita verso una dipendenza:
sudo ss -tan '( dport = :6379 )'
Questa distinzione cambia la conversazione successiva. Se l'HTTPS in entrata si sta accumulando, potresti dover ispezionare il bilanciatore di carico, la terminazione TLS, i limiti dei worker o il comportamento del client. Se le connessioni Redis in uscita si stanno accumulando, l'applicazione locale potrebbe creare troppe connessioni client, aspettare Redis o riprovare in modo troppo aggressivo.
Quando hai bisogno di un conteggio rapido senza leggere centinaia di righe, combina ss con semplici strumenti shell:
sudo ss -tan state established '( dport = :443 )' | wc -l
sudo ss -tan state established '( dport = :5432 )' | wc -l
Il conteggio include la riga di intestazione, quindi non è una metrica perfetta. Per il triage, è comunque utile. Se il numero raddoppia ogni minuto durante un incidente, hai un segnale più forte di un singolo snapshot.
Contenitori e Namespace di Rete
Su host containerizzati, fai attenzione a dove esegui il comando. Eseguire ss sull'host mostra i namespace di rete dell'host e le porte pubblicate, ma potrebbe non mostrare la stessa vista che il processo vede all'interno del suo contenitore. Se un servizio viene eseguito in un contenitore, confronta entrambe le viste:
sudo ss -tulpen
docker exec <contenitore> ss -tulpen
Per Kubernetes, usa la vista del nodo per i listener a livello di host e kubectl exec per il namespace di rete del pod. Una porta può essere aperta all'interno del contenitore mentre l'host, il servizio, l'ingress o la policy di rete impediscono ancora al traffico di raggiungerla. ss è uno strumento di verità locale, non un test di connettività end-to-end.
Best Practices per la Risoluzione dei Problemi di Rete
- Usa Sempre
-n: Quando risolvi problemi di prestazioni o scrivi script, usa il flag numerico (-n) per evitare ritardi di risoluzione DNS, che possono rendere lente le diagnosi. - Dai Priorità a
ss: Adottasscome tuo strumento predefinito. Riservanetstatsolo per sistemi legacy in cuissnon è disponibile. - Esegui come Root per il PID: Per vedere quale programma sta usando una porta, generalmente hai bisogno di
sudoo privilegi di root quando usi il flag-pcon entrambe le utility. - Controlla le Statistiche dell'Interfaccia: Non dimenticare i contatori di interfaccia. Usa
ip -s link show <nome_interfaccia>per verificare la presenza di pacchetti persi o errori, che potrebbero indicare un problema a livello fisico piuttosto che un problema di socket. - Confronta gli snapshot. Un output di
ssè una fotografia. Due output presi a un minuto di distanza ti dicono se la situazione sta crescendo, diminuendo o è stabile. - Scrivi il filtro esatto. Durante gli incidenti, un comando salvato come
ss -tan '( dport = :5432 )'è più facile da ripetere e confrontare rispetto a un pipeline grep ricordato a metà.
L'abitudine che ripaga è semplice: inizia con i listener, passa agli stati delle connessioni, identifica il processo proprietario, poi decidi se il passo successivo appartiene all'app, al percorso di rete, al firewall o al kernel.