Torna al blog
31 agosto 2026Sergei Solod9 min di lettura

Il mio VPS FDCServers ha gestito senza problemi oltre 3 TB di traffico. Poi le letture dal disco hanno iniziato a richiedere 18 secondi

Il mio VPS FDCServers inizialmente ha gestito traffico reale senza problemi e trasferito più di 3 TB di dati. Poi il normale workload ha iniziato a provocare gravi stall del disco virtuale: CPU iowait al 100%, pressione I/O di Linux quasi al 100%, letture fino a 18,7 secondi e flush oltre 53 secondi.

FDCServersVPSLinuxI/O discoDevOps

Non sto scrivendo questo articolo come recensione negativa di FDCServers. Non voglio nemmeno dire agli altri se dovrebbero o meno acquistare un VPS da loro. Ho avuto un server, un workload e una determinata sequenza di problemi. Non basta per giudicare un intero provider.

È semplicemente uno dei miei giorni da sviluppatore. Il VPS aveva funzionato normalmente per un po' e aveva già trasferito più di 3 TB di traffico. Poi il normale workload ha cominciato a produrre ritardi enormi. Le pagine potevano impiegare moltissimo a rispondere o andare completamente in timeout. All'inizio i sospetti erano quelli classici: applicazione, Nginx, memoria, rete, limiti di connessione o troppo carico. Le metriche Linux indicavano qualcos'altro.

Il VPS non era lento fin dall'inizio

Tra un episodio e l'altro, la macchina poteva sembrare perfettamente sana. Durante un periodo normale non c'erano processi in D-state, il CPU iowait era intorno allo 0%, la latenza del disco circa 2–4 ms e l'I/O PSI quasi a zero:

D-state processes: 0
CPU iowait:        ~0%
disk latency:      ~2–4 ms
I/O PSI some:      0.04
I/O PSI full:      0.04

Se mi fossi collegato solo in quel momento e avessi controllato top, free -h, df -h e systemctl status nginx, probabilmente avrei concluso che il VPS stava bene. Poi è tornato il workload normale e lo stato della macchina è cambiato drasticamente.

Letture da 18,7 secondi hanno cambiato l'indagine

Uno dei campioni iostat più significativi era questo:

r_await = 18744 ms
f_await = 53561 ms
aqu-sz  = 128.54
util    = 100.10%
read    = 88 KB/s

I numeri contano insieme. Le letture completate avevano una latenza media di circa 18,7 secondi. La latenza di flush era circa 53,6 secondi. La coda I/O media superava 128, mentre il throughput di lettura utile era appena 88 KB/s. Non era semplicemente un disco occupato a spostare molti dati. Il percorso storage trascorreva una quantità enorme di tempo in attesa che le operazioni terminassero.

iowait e PSI mostravano pressione I/O sull'intero sistema

Nei periodi peggiori, vmstat mostrava 4–9 processi bloccati, CPU iowait intorno al 97–100% e CPU idle allo 0%. iowait non significa che l'applicazione stia consumando tutta la CPU. Significa che il lavoro utile sta aspettando operazioni I/O ancora pendenti.

Linux Pressure Stall Information rendeva il quadro ancora più chiaro:

I/O PSI some avg10 = 99.14
I/O PSI full avg10 = 95.55

Nelle riproduzioni successive, full si è avvicinato al 98%. L'utilizzo del disco mi dice che un dispositivo è occupato; PSI mi dice quanto il workload sia effettivamente bloccato da quella risorsa. Una pressione I/O persistente del 95–98% non è una piccola regressione delle prestazioni.

D-state e kernel stack indicavano un livello sotto l'applicazione

Ho quindi controllato quali processi fossero bloccati. Nello stesso momento vedevo jbd2, systemd-journald, worker Nginx, processi cache di Nginx e altra attività del filesystem in D-state. Se fosse rimasta bloccata solo l'applicazione, avrei indagato sull'applicazione. Quando Nginx, il journal di sistema e il journal EXT4 si bloccano insieme, lo storage diventa la dipendenza comune più evidente.

I percorsi di journaling EXT4 includevano:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

I worker Nginx aspettavano in normali letture di file:

folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64

A un certo punto il kernel ha segnalato che un task Nginx era bloccato da oltre 122 secondi. Nginx poteva ancora risultare active, ma questo non significava che i suoi worker riuscissero a completare lavoro utile. running e sano sono stati diversi.

Una risposta backend in 3 ms ha separato l'applicazione dal filesystem

Il confronto più pulito è stato tra Nginx e il backend locale. Le richieste tramite Nginx restituivano HTTP=000 per timeout di connessione o TLS. Una richiesta diretta al backend terminava in circa 3 ms:

connect = 0.000423 s
TTFB    = 0.003063 s
total   = 0.003139 s

Lo status HTTP esatto non era importante per questo test. Il backend accettava la connessione, elaborava la richiesta e produceva una risposta quasi immediatamente. Nello stesso momento, i worker Nginx erano visibilmente in attesa di letture EXT4. Questo separava l'esecuzione normale dell'applicazione dal percorso dipendente dal filesystem che aveva davanti.

Il problema era riproducibile e poteva anche sparire

Prima di una riproduzione, la macchina sembrava normale:

HTTP:          200
D-state:       0
CPU iowait:    3%
r_await:       ~1.18 ms
I/O PSI full:  ~2.95%

Circa mezzo minuto dopo:

D-state:       4
CPU iowait:    91%
CPU idle:      0%
I/O PSI some:  86.11%
I/O PSI full:  78.02%
r_await:       236.50 ms
HTTP:          000

Più tardi il CPU iowait ha raggiunto il 96–100%, l'I/O PSI full si è avvicinato al 98%, la coda HTTPS è arrivata a 512 e i controlli HTTP continuavano a fallire. Era un'evidenza molto più utile che dire semplicemente che il VPS sembrava lento.

Rimuovendo il workload, la transizione opposta poteva verificarsi rapidamente:

D-state:      0
CPU iowait:   6%
r_await:      ~0.98 ms
queue depth:  ~0.07
HTTP:         200

Ecco perché i problemi storage intermittenti sono difficili da analizzare a posteriori. Il provider può controllare il server dopo il recovery e vedere realmente una latenza normale. Ma questo non spiega ciò che è successo dieci minuti prima. I timestamp UTC precisi sono diventati essenziali.

Due metriche che possono trarre in inganno: await=0 e spazio libero

Durante alcuni intervalli problematici vedevo r_await = 0 mentre iowait era alto, i processi erano in D-state, le richieste restavano in-flight e quasi nessuna lettura terminava. Le statistiche di latenza si basano sull'I/O completato. Se un'operazione resta bloccata e non termina durante la finestra di campionamento, non può contribuire alla latenza delle operazioni concluse. Perciò zero non significa sempre un disco istantaneo.

Ho considerato anche il riempimento del filesystem. Più avanti è diventato più pieno di quanto normalmente permetterei, ma lo stesso tipo di failure era già comparso quando il root filesystem era utilizzato solo per circa il 24%. In quel momento erano disponibili circa 1,2 GiB di RAM, l'uso degli inode era circa il 5% e l'interfaccia di rete non mostrava errori né pacchetti scartati. Il riempimento del disco non poteva spiegare l'intero incidente.

Cosa potevo dimostrare e cosa no

Dall'interno del VPS potevo osservare l'applicazione, Linux VFS, EXT4 e il virtual block device. Dopo inizia l'infrastruttura del provider: virtualizzazione, storage distribuito, rete storage, dispositivi fisici, scheduling e altri livelli che non posso ispezionare dal guest.

Quindi non posso affermare onestamente che uno specifico SSD fisico fosse guasto, né indicare uno specifico storage node, percorso di rete o componente di virtualizzazione come root cause.

Posso dire qualcosa di più circoscritto ma ben supportato: il percorso di storage virtuale presentato al mio guest Linux entrava ripetutamente in stati nei quali normali operazioni I/O del filesystem richiedevano secondi o non terminavano in un tempo ragionevole. Le prove provenivano da iostat, PSI, D-state, kernel wait stack, attese EXT4/jbd2, attese filesystem di Nginx, profondità delle code e tempi delle richieste. Era sufficiente per la diagnosi tecnica di cui avevo bisogno, ma non per identificare una causa fisica.

Perché gli oltre 3 TB di traffico precedente non contraddicono gli stall successivi

All'inizio questo mi confondeva. Se lo storage aveva problemi, come aveva fatto il VPS a trasferire diversi terabyte con successo?

Perché il traffico di rete non è la stessa cosa dell'I/O fisico del disco. Un file può essere letto una volta dal backing storage, restare nella page cache Linux e poi essere servito molte volte dalla memoria. Tre terabyte trasferiti in rete non significano quindi tre terabyte di letture fisiche uniche.

Anche le condizioni dell'infrastruttura cambiano nel tempo: stato della cache, carico storage, queueing, host placement e altri workload possono variare. Un VPS che ieri funzionava normalmente non garantisce identico comportamento dello storage oggi.

Alla fine ho smesso di aspettare una root cause più profonda

Ho raccolto timestamp precisi, vmstat, iostat, PSI, snapshot dei processi bloccati, kernel stack, attese del filesystem, profondità delle code e timing HTTP. Ho inviato la diagnostica a FDCServers e ho aspettato una spiegazione più approfondita a livello di infrastruttura.

Ho aspettato a lungo. Alla fine ho smesso. Dal mio punto di vista sapevo già abbastanza per prendere una decisione operativa: il problema era riproducibile, grave, visibile sotto il livello applicativo e la causa fisica era fuori dalla visibilità del mio VPS.

Ho chiesto un rimborso e FDCServers ha restituito il denaro

Ho inviato a FDCServers un riepilogo dei problemi e della diagnostica raccolta, ho chiesto di annullare il servizio e ho richiesto un rimborso. Mi hanno rimborsato.

Quindi questa storia non termina con una lunga battaglia economica. Ho aspettato una spiegazione tecnica definitiva, ho deciso che non volevo aspettare oltre, ho inviato le prove che avevo e ho chiesto indietro il denaro. FDCServers lo ha restituito.

Cosa ho cambiato dopo

Il risultato utile non è stato decidere se una società di hosting fosse buona o cattiva. È cambiato il mio modo di diagnosticare server Linux lenti.

Uso ancora top, free -h e df -h, ma ora passo molto prima a:

date -u
uptime
cat /proc/pressure/io
cat /proc/pressure/memory
cat /proc/pressure/cpu
vmstat 1 10
iostat -x 1 10
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
ss -lntp
journalctl -k --since '30 min ago' --no-pager

Quando possibile, testo anche i diversi request path separatamente: richiesta pubblica, Nginx locale, backend diretto, filesystem e metriche del block device. La domanda non è più semplicemente perché il server è lento. È: a quale livello il lavoro utile smette di completarsi?

Quando posso, raccolgo le prove prima di un reboot. Il riavvio può ripristinare il servizio, ma può anche cancellare esattamente D-state, PSI, code e latenza che rendono diagnosticabile un incidente intermittente.

Considerazione finale

Non ho comprato un VPS FDCServers perché cercavo materiale per un articolo sull'hosting. Volevo un server con molta banda. Per un po' ho ottenuto esattamente questo: ha gestito carico reale e trasferito più di tre terabyte.

Poi il normale workload ha iniziato a produrre in modo riproducibile iowait fino al 100%, I/O PSI vicino al 100%, letture fino a 18,7 secondi, flush oltre 53 secondi, grandi code, Nginx bloccato nelle letture del filesystem e EXT4/jbd2 in attesa di I/O.

Non ho mai saputo quale componente fisico o host-side ne fosse la causa e non ho bisogno di fingere il contrario. Ho identificato il livello in cui il problema si manifestava, raccolto prove sufficienti per distinguerlo da un problema dell'applicazione, smesso di aspettare una spiegazione più profonda e chiesto indietro il denaro. FDCServers mi ha rimborsato.

Questo non è un verdetto su ogni VPS FDCServers. È un promemoria ben documentato: un servizio può apparire active, un processo running, mentre la macchina trascorre quasi tutto il suo tempo utile aspettando lo storage.