Risoluzione dei Problemi di Esaurimento delle Risorse Linux: CPU, Memoria e Spazio su Disco
Risolvi i problemi di esaurimento di CPU, memoria e disco su Linux con comandi pratici, passaggi di pulizia sicuri e controlli delle cause profonde.
Risoluzione dei Problemi di Esaurimento delle Risorse Linux: CPU, Memoria e Spazio su Disco
Quando un server Linux esaurisce CPU, memoria o spazio su disco, il primo sintomo è solitamente vago: il sito è lento, SSH si blocca dopo il login, i deployment falliscono o un servizio continua a riavviarsi. Il modo più rapido per gestire l'incidente è identificare quale risorsa è esaurita, quindi trovare il processo o il filesystem responsabile.
Esegui prima i controlli meno rischiosi. Comandi di sola lettura come top, free, df, du, vmstat e journalctl ti forniscono un quadro senza modificare la macchina. Uccidere processi ed eliminare file può essere necessario, ma non è una diagnosi.
Identificare il Colpevole: Monitoraggio delle Risorse di Sistema
Prima di poter risolvere un problema di esaurimento delle risorse, devi individuare quale risorsa è sovrautilizzata e quale processo è responsabile. Linux fornisce un ricco set di strumenti da riga di comando per questo scopo.
Monitoraggio dell'Utilizzo della CPU
Un utilizzo elevato della CPU può rendere il sistema lento e poco reattivo. Spesso è causato da un processo incontrollato, un'applicazione impegnativa o uno script inefficiente.
top: Questo è un monitor di sistema in tempo reale indispensabile. Mostra un elenco dinamico dei processi, ordinati per utilizzo della CPU per impostazione predefinita. Puoi vedere l'utilizzo complessivo della CPU, l'utilizzo della memoria e i dettagli dei singoli processi.topAll'interno di
top, premi1per vedere l'utilizzo dei singoli core della CPU. PremiPper ordinare per utilizzo della CPU. Cerca i processi che consumano costantemente una percentuale elevata di CPU.htop: Una versione interattiva migliorata ditop. È spesso preferito per la sua facilità d'uso, l'output colorato e la navigazione più semplice.htopSimile a
top,htopconsente di ordinare per utilizzo della CPU e fornisce informazioni dettagliate sui processi.mpstat: Parte del pacchettosysstat,mpstatfornisce statistiche dettagliate della CPU, inclusi l'utilizzo per processore, i conteggi degli interrupt e i cambi di contesto.mpstat -P ALL 1Questo comando mostrerà le statistiche della CPU per tutti i core ogni secondo.
Controlla anche il carico medio rispetto al numero di CPU:
uptime
nproc
Un carico medio di 8 significa qualcosa di molto diverso su una VM a 2 core rispetto a un host a 32 core. Il carico include anche le attività in attesa di I/O non interruptibile, quindi un carico medio elevato con un basso utilizzo della CPU potrebbe effettivamente indicare un problema con il disco o l'archiviazione di rete.
Monitoraggio dell'Utilizzo della Memoria
Quando un sistema esaurisce la RAM disponibile e lo spazio di swap, inizia a utilizzare lo spazio su disco come memoria virtuale, che è significativamente più lenta, portando a un grave degrado delle prestazioni.
free -h: Mostra la quantità totale di memoria fisica e di swap libera e utilizzata nel sistema, insieme ai buffer e alle cache utilizzati dal kernel. Il flag-hrende l'output leggibile dall'uomo (ad esempio, MB, GB).free -hPresta attenzione alla memoria
disponibilee allo spazio di swaputilizzato. Un utilizzo elevato dello swap indica RAM insufficiente.top/htop: Siatopchehtopmostrano l'utilizzo della memoria per processo. Cerca i processi con un valore%MEMelevato.vmstat: Riporta le statistiche della memoria virtuale. Può mostrare informazioni su processi, memoria, paginazione, I/O su blocchi, trap e attività della CPU.vmstat 5Questo comando riporterà le statistiche ogni 5 secondi. Osserva le colonne
si(swap-in) eso(swap-out); valori elevati indicano un significativo swapping della memoria.
Per possibili kill OOM, controlla il log del kernel:
dmesg -T | grep -i 'killed process'
journalctl -k --since "1 hour ago" | grep -i oom
Un kill OOM cambia l'incidente. La domanda immediata diventa quale processo è stato ucciso, perché ha superato la memoria disponibile e se systemd o un orchestrator lo ha riavviato.
Monitoraggio dello Spazio su Disco
Una partizione del disco piena può impedire alle applicazioni di scrivere dati, causare errori e persino impedire l'avvio del sistema.
df -h: Riporta l'utilizzo dello spazio su disco del filesystem. Il flag-hrende l'output leggibile dall'uomo.df -hQuesto comando elencherà tutti i filesystem montati e mostrerà la loro dimensione totale, lo spazio utilizzato, lo spazio disponibile e il punto di mount. Cerca le partizioni al 100% o quasi.
du -sh <directory>: Stima l'utilizzo dello spazio su file per una determinata directory. Il flag-sriassume e-hlo rende leggibile dall'uomo.du -sh /var/log/*Usalo per trovare quali sottodirectory consumano più spazio su disco.
Controlla anche l'utilizzo degli inode:
df -ih
Un filesystem può avere gigabyte liberi ed essere comunque impossibilitato a creare file se ha esaurito gli inode. Questo accade con milioni di file piccoli: voci di cache, code di posta, file di sessione, artefatti di build o log mal ruotati.
Risolvere i Problemi di Esaurimento delle Risorse
Una volta identificata la risorsa problematica e il processo incriminato, puoi adottare misure per risolvere il problema.
Affrontare l'Utilizzo Elevato della CPU
- Identificare il Processo: Usa
topohtopper trovare l'ID del processo (PID) che consuma molta CPU. - Investigare il Processo: Determina cos'è il processo. È un'applicazione utente, un servizio di sistema o qualcosa di inaspettato?
- Utilizzo Elevato Legittimo: Se un'applicazione legittima utilizza molta CPU (ad esempio, compilazione di software, codifica video), potresti dover attendere che finisca, programmarla per le ore non di punta o aggiornare l'hardware.
- Processo Incontrollato: Se un processo è bloccato in un ciclo o consuma CPU eccessiva involontariamente, puoi provare a riavviarlo. Se non funziona, potresti doverlo terminare.
- Terminare il Processo (Usare con Cautela!): Puoi usare il comando
killper inviare segnali ai processi. I segnali più comuni sono:SIGTERM(15): Chiede gentilmente al processo di terminare.SIGKILL(9): Termina forzatamente il processo immediatamente. Dovrebbe essere l'ultima risorsa poiché non consente al processo di eseguire la pulizia.
# Termina gentilmente il processo con PID 1234 kill 1234 # Termina forzatamente il processo con PID 1234 kill -9 1234 - Controllare i Log: Esamina i log di sistema (ad esempio,
/var/log/syslog,/var/log/messages, log specifici dell'applicazione) per errori relativi al processo problematico. - Ottimizzare Applicazioni/Script: Se l'utilizzo elevato della CPU è dovuto a un'applicazione o uno script inefficiente, considera di ottimizzare il codice o la configurazione.
La CPU elevata non è sempre negativa. Un job batch che utilizza tutti i core per un breve periodo può andare bene. Un processo single-thread bloccato al 100% di un core mentre le richieste si accodano dietro è diverso. Osserva la durata, l'impatto sull'utente e se ci si aspetta che il processo sia occupato.
Se hai bisogno di più contesto prima di riavviare un servizio, cattura un'istantanea:
ps -fp <pid>
sudo lsof -p <pid> | head
sudo strace -p <pid> -tt -T -f
Usa strace con attenzione sui sistemi di produzione. Può aggiungere overhead, ma un breve campione spesso ti dice se il processo è in loop, in attesa su file, sta fallendo chiamate di rete o sta aprendo ripetutamente la stessa risorsa.
Risolvere Perdite di Memoria ed Esaurimento
Una perdita di memoria si verifica quando un programma non rilascia la memoria di cui non ha più bisogno, consumando gradualmente tutta la RAM disponibile. Questo può portare a swapping eccessivo e a un sistema non reattivo.
- Identificare il Processo: Usa
topohtopper trovare i processi con memoria elevata (%MEM) o valori RSS (resident set size) che aumentano costantemente nel tempo. - Investigare il Processo: Determina la natura dell'applicazione. È un'applicazione nota con potenziali problemi di memoria o qualcosa di personalizzato?
- Riavviare l'Applicazione/Servizio: Spesso, il semplice riavvio dell'applicazione o del servizio può risolvere temporaneamente una perdita di memoria liberando la memoria accumulata.
# Esempio: Riavvio del server web Apache sudo systemctl restart apache2 - Controllare il Monitoraggio Specifico dell'Applicazione: Molte applicazioni (ad esempio, server web, database) hanno i propri strumenti di monitoraggio o log che possono aiutare a diagnosticare i problemi di memoria.
- Analizzare i Core Dump: Per le applicazioni critiche, potresti dover abilitare i core dump e utilizzare strumenti di debug (come
gdb) per analizzare lo stato della memoria quando si verifica la perdita. Questo è un passaggio di risoluzione dei problemi avanzato. - Aumentare lo Spazio di Swap (Misure Temporanee): Se non puoi risolvere immediatamente la perdita, puoi aumentare lo spazio di swap per fornire più memoria virtuale. Tuttavia, questa è una soluzione alternativa, non una soluzione.
- Aggiornamento Hardware: Se il tuo sistema esaurisce costantemente la memoria per il suo carico di lavoro, potresti dover aggiungere più RAM fisica.
Un'indagine migliore sulla memoria osserva il cambiamento nel tempo. Uno screenshot di top dice solo chi è grande ora. Una perdita è una tendenza.
while true; do
date
ps -eo pid,comm,rss,%mem --sort=-rss | head -15
sleep 60
done
Se lo stesso processo sale costantemente tra i campioni senza scendere dopo che il traffico cala, hai un segnale di perdita più forte. Se molti processi crescono insieme durante il traffico di punta, il carico di lavoro potrebbe semplicemente superare la capacità o i limiti di concorrenza.
Per i servizi systemd, controlla se esistono già limiti di memoria:
systemctl show <service> -p MemoryCurrent -p MemoryMax
Per i container, free -h a livello di host potrebbe sembrare a posto mentre un container raggiunge il proprio limite. Controlla docker stats, kubectl top pod o gli eventi dell'orchestrator per kill OOM.
Gestire Partizioni Disco Piene
Quando una partizione del disco si riempie, può causare vari guasti al sistema. Di solito è richiesta un'azione immediata.
- Identificare la Partizione Piena: Usa
df -hper individuare la o le partizioni al 100% di capacità. - Trovare File/Directory Grandi: Usa
du -shodu -h --max-depth=1 <directory>per navigare nell'albero delle directory e trovare cosa consuma spazio.
I colpevoli comuni includono file di log (# Trova le directory più grandi nella partizione root sudo du -h --max-depth=1 / | sort -rh/var/log), file temporanei (/tmp), cache dei pacchetti e dati utente. - Pulire i File di Log: I file di log possono diventare molto grandi. Spesso puoi eliminare in sicurezza i vecchi log o configurare la rotazione dei log (
logrotate) per gestire automaticamente le loro dimensioni.- Eliminare Vecchi Log: Fai attenzione e assicurati di non eliminare log attualmente attivi. Puoi usare
findper eliminare file più vecchi di un certo numero di giorni.# Elimina file .log più vecchi di 30 giorni in /var/log/myapp sudo find /var/log/myapp -name "*.log" -type f -mtime +30 -delete - Rotazione dei Log: Assicurati che
logrotatesia configurato correttamente per i tuoi servizi. Di solito viene eseguito quotidianamente e gestisce l'archiviazione e l'eliminazione dei vecchi log.
- Eliminare Vecchi Log: Fai attenzione e assicurati di non eliminare log attualmente attivi. Puoi usare
- Pulire la Cache del Gestore di Pacchetti: I gestori di pacchetti spesso conservano i file dei pacchetti scaricati. Pulirli può liberare spazio significativo.
- Debian/Ubuntu (apt):
sudo apt autoremove sudo apt clean - CentOS/RHEL/Fedora (yum/dnf):
sudo yum autoremove # o dnf autoremove sudo yum clean all # o dnf clean all
- Debian/Ubuntu (apt):
- Rimuovere Pacchetti Inutilizzati: Disinstalla il software che non ti serve più.
- Debian/Ubuntu:
sudo apt remove <nome_pacchetto> - CentOS/RHEL/Fedora:
sudo yum remove <nome_pacchetto>osudo dnf remove <nome_pacchetto>
- Debian/Ubuntu:
- Controllare le Directory Temporanee: I file in
/tmpsono spesso sicuri da eliminare, specialmente dopo un riavvio, ma fai attenzione se le applicazioni li stanno usando attivamente. - Svuotare il Cestino: Se stai usando un ambiente desktop, controlla i cestini degli utenti.
- Considerare il Ridimensionamento delle Partizioni: Se lo spazio è costantemente un problema e la pulizia non è sufficiente, potresti dover ridimensionare le partizioni o aggiungere più storage. Questa è un'operazione più avanzata che potrebbe richiedere lo smontaggio delle partizioni o l'avvio da un ambiente live.
Fai attenzione ai file eliminati che sono ancora aperti. df potrebbe mostrare un filesystem pieno anche dopo aver rimosso un file di log di grandi dimensioni, perché un processo in esecuzione ha ancora l'handle del file aperto.
sudo lsof +L1
Se un file eliminato è ancora tenuto aperto, il riavvio o il ricaricamento del servizio proprietario rilascia lo spazio. Fallo intenzionalmente; non riavviare un database o un servizio critico nel bel mezzo di un incidente senza comprenderne l'impatto.
Per i log di journal, preferisci la pulizia con journalctl rispetto all'eliminazione manuale dei file:
journalctl --disk-usage
sudo journalctl --vacuum-time=14d
Per gli host Docker, controlla i log dei container e le immagini inutilizzate:
docker system df
docker ps --size
Non eseguire comandi di pulizia generici alla cieca su un host di produzione. Possono rimuovere immagini, cache di build, container fermati e reti che qualcuno si aspettava di mantenere.
Un Ordine di Triage che Funziona Sotto Pressione
Quando tutto è lento, usa un ordine fisso in modo da non saltare tra teorie.
Conferma che l'host è raggiungibile e non in sola lettura:
uptime date mount | grep ' ro,'Controlla CPU e carico:
top uptimeControlla memoria e swap:
free -h vmstat 1 5Controlla spazio su disco e inode:
df -h df -ihControlla errori recenti del kernel e dei servizi:
journalctl -p warning..alert --since "30 minutes ago" journalctl -k --since "30 minutes ago"
Questo ordine cattura rapidamente i guasti comuni: saturazione della CPU, tempeste di swap, filesystem pieni, esaurimento degli inode, kill OOM ed errori di archiviazione.
Scegliere la Soluzione Immediata Meno Peggiore
Durante un'interruzione, potresti aver bisogno di una soluzione a breve termine prima che la soluzione permanente sia pronta.
Per l'esaurimento della CPU, un riavvio graduale del servizio può essere più sicuro di kill -9, specialmente per software che scrive stato. Se un job batch sta affamando il traffico utente, abbassa la sua priorità:
sudo renice +10 -p <pid>
sudo ionice -c2 -n7 -p <pid>
Per l'esaurimento della memoria, ridurre la concorrenza è spesso più sicuro che aggiungere swap e sperare. Abbassa i conteggi dei worker web, metti in pausa i job batch o disabilita temporaneamente le funzionalità costose. Lo swap può far guadagnare tempo, ma uno swap pesante di solito trasforma un guasto chiaro in un guasto lento.
Per l'esaurimento del disco, elimina o ruota i file che conosci. Buoni candidati sono i vecchi log compressi, le cache dei pacchetti, gli artefatti di build obsoleti e i file temporanei di job fermati. Cattivi candidati sono i file di database, i log attivi, i file sconosciuti nelle directory dei dati dell'applicazione e qualsiasi cosa tu non possa spiegare.
Note sulla Causa Radice da Catturare
Dopo che il sistema è stabile, scrivi cosa è cambiato. Le note utili sono concrete:
- Il filesystem o la risorsa esatta che era esaurita.
- Il processo, l'utente, il servizio, il container o il cron job coinvolto.
- L'output del comando che lo ha dimostrato.
- L'azione immediata intrapresa.
- La correzione permanente necessaria.
Questa non è burocrazia fine a se stessa. Il prossimo incidente è molto più facile quando sai che /var si è riempito perché i log di debug sono cresciuti dopo un deploy, o che la pressione della memoria è iniziata quando il numero di worker è raddoppiato.
Best Practice per la Prevenzione
- Monitoraggio Regolare: Implementa il monitoraggio regolare di CPU, memoria e spazio su disco utilizzando strumenti come
top,htop,free,dfe soluzioni di monitoraggio dedicate (ad esempio, Nagios, Zabbix, Prometheus). - Automatizzare la Rotazione dei Log: Assicurati che
logrotatesia configurato correttamente per tutti i servizi che generano log. - Ottimizzare le Configurazioni delle Applicazioni: Ottimizza le impostazioni dell'applicazione per essere più efficienti in termini di risorse. Ad esempio, ottimizza i processi worker del server web, i pool di connessione del database, ecc.
- Impostare Avvisi: Configura avvisi per utilizzo elevato sostenuto, crescita rapida, kill OOM, pienezza del filesystem, esaurimento degli inode e riavvii dei servizi. Avvisa sulle tendenze, non solo sui limiti rigidi.
- Aggiornamenti di Sistema: Mantieni aggiornati il sistema e le applicazioni, poiché i miglioramenti delle prestazioni e le correzioni di bug sono spesso inclusi nelle versioni più recenti.
- Limiti delle Risorse: Per i sistemi multiutente o gli ambienti containerizzati, considera l'impostazione di limiti delle risorse (ad esempio, usando
ulimito cgroups) per impedire a un singolo processo di affamare gli altri.
La risoluzione dei problemi di esaurimento delle risorse è principalmente un restringimento disciplinato. Trova la risorsa limitata, identifica il proprietario, apporta la modifica stabilizzante più piccola, quindi correggi il motivo per cui è successo. Gli strumenti di base sono sufficienti per la maggior parte degli incidenti se li usi in quest'ordine e resisti all'impulso di eliminare o uccidere prima di capire cosa stai toccando.