Terug naar de blog
31 augustus 2026Sergei Solod11 min leestijd

Mijn VPS was online. Toen begon Linux 18 seconden op disk reads te wachten

Een praktijkverhaal over Linux-debugging in productie: de VPS bleef online terwijl nuttig werk bijna stilviel. De I/O-druk naderde 100%, reads liepen op tot 18,7 seconden en Nginx blokkeerde in EXT4, terwijl de backend zelf nog in ongeveer 3 ms antwoordde.

LinuxDevOpsVPSPrestatiesDebugging

Voordat ik bij de debugging kom, wil ik één ding duidelijk maken: mijn algemene indruk van FDCServers is niet negatief. Dit is geen review die mensen vertelt de provider te vermijden en ook geen oordeel over hun volledige infrastructuur. Ik had één VPS, gedurende één periode, met één ongewoon lastig probleem.

Lange tijd werkte die VPS normaal en verwerkte hij echt productieverkeer zonder problemen. Daarna veranderde er iets. Gewone requests begonnen absurd lang te duren. Pagina's openden eerst traag en soms helemaal niet meer. Op andere momenten zag de machine er alweer normaal uit voordat ik de storing goed kon onderzoeken.

Op het slechtste moment legde ik dit vast:

CPU iowait:       97–100%
I/O PSI full:     ~95–98%
read latency:     up to 18.7 seconds
flush latency:    up to 53.6 seconds
I/O queue depth:  128+

Nginx draaide. Mijn backend draaide. De VM was online. En toch kwam er bijna geen nuttig werk meer vooruit.

De productiestoring was frustrerend, maar de debugging zelf vond ik oprecht interessant. Dit is precies waarom ik Linux zo waardeer: een machine kan er van buiten levend uitzien terwijl meerdere onafhankelijke kernelinterfaces laten zien waar nuttige voortgang daadwerkelijk stopt. Dit artikel gaat over het volgen van die signalen, niet over de vraag of FDCServers een goede of slechte provider is.

active (running) bleek bijna niets te betekenen

Ik begon met de voor de hand liggende controles:

top
free -h
df -h
systemctl status nginx

In gezonde periodes zag ik ongeveer:

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

Als ik alleen op zo'n moment had ingelogd, had ik makkelijk geconcludeerd dat de VPS gezond was. Daarna kwam normaal verkeer terug en kon de toestand volledig omslaan. Een gezonde snapshot van een intermitterend systeem zegt weinig over de toestand tijdens de storing. Ik moest bewijs verzamelen terwijl het probleem daadwerkelijk optrad.

De iostat-meting die het onderzoek veranderde

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

Afgeronde reads duurden ongeveer 18,7 seconden. Flushes duurden ongeveer 53,6 seconden. De gemiddelde queue lag boven 128, terwijl de nuttige read-throughput maar 88 KB/s was.

Dit zag er niet uit als storage die gewoon druk was omdat hij efficiënt een zware workload bediende. Het virtuele block-pad was praktisch verzadigd terwijl er heel weinig werk werd voltooid. Hoge utilization alleen is geen storing, maar hoge utilization in combinatie met enorme latency, een lange queue, geblokkeerde taken, minieme throughput en mislukte requests is een heel ander signaal.

Ik stopte met iowait als diagnose te behandelen

blocked processes: 4–9
CPU iowait:        97–100%
CPU idle:          0%

Het is verleidelijk om dit samen te vatten als “de CPU wachtte 100% van de tijd op de disk”. Als intuïtie is dat bruikbaar, maar Linux-accounting is ingewikkelder en iowait is geen directe meting van de disk zelf. Daarom behandelde ik het als één symptoom en zocht ik naar onafhankelijk bewijs.

PSI liet zien dat I/O nuttig werk stopzette

cat /proc/pressure/io

Tijdens een ernstige periode:

some avg10=99.14
full avg10=95.55

Bij latere reproducties kwam full in de buurt van 98%. Bij I/O-pressure staat some voor tijd waarin ten minste een deel van het niet-idle werk op I/O wacht, terwijl full tijd aangeeft waarin alle niet-idle taken tegelijkertijd op I/O vastlopen. Een waarde bij 100% zegt veel meer dan alleen dat een disk druk is: de workload krijgt nauwelijks gelegenheid om vooruit te komen.

D-state liet me stoppen één proces de schuld te geven

ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'

Dat één proces kort in D-state staat, bewijst geen storageprobleem. Belangrijk was welke processen tegelijk vastzaten. Ik zag onder andere jbd2, systemd-journald, Nginx-workers, Nginx-cacheprocessen en andere filesystemactiviteit.

Als alleen mijn backend vastloopt, onderzoek ik de backend. Als alleen Nginx vastloopt, onderzoek ik Nginx. Maar wanneer Nginx, het system journal en de EXT4-journalthread tegelijk niet meer vooruitkomen, wordt hun gedeelde afhankelijkheid veel interessanter. In dit geval waren dat het filesystem en het storagepad daaronder.

De kernel stacks lieten de volgende laag zien

De EXT4-journalthread verscheen in paden zoals:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

Nginx-workers verschenen in gewone filesystem-readpaden:

folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64

Op een moment rapporteerde de kernel:

INFO: task nginx blocked for more than 122 seconds.

systemctl status nginx kon nog steeds active (running) tonen. Beide observaties waren waar: het proces bestond, maar een Nginx-task kon al meer dan twee minuten geen nuttig werk afronden. Een draaiend proces en een gezonde service zijn niet hetzelfde.

Mijn duidelijkste experiment duurde ongeveer drie milliseconden

Een request via Nginx mislukte:

HTTP=000
SSL connection timeout

Daarna omzeilde ik Nginx en benaderde ik de lokale backend rechtstreeks:

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

Ongeveer 3 ms. De precieze HTTP-status was voor deze test niet belangrijk. De backend accepteerde de verbinding, voerde de request uit en stuurde bijna direct een response terug. Rond hetzelfde moment waren Nginx-workers zichtbaar in EXT4-readpaden.

application execution       → progressing normally
filesystem-backed web path  → not progressing normally

Hoe dieper ik ging, hoe minder aannemelijk een oorzaak op applicatieniveau werd.

Dezelfde VPS kon in ongeveer 30 seconden instorten

Voor één reproductie:

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

Ongeveer een halve minuut later:

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

Later verslechterde het verder:

CPU iowait:    96–100%
I/O PSI full:  ~98%
HTTPS queue:   512
HTTP:          000

Toen ik de workload weghaalde, kon de omgekeerde overgang snel gebeuren:

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

Daarom zijn intermitterende infrastructuurproblemen zo lastig. Tien minuten later kan iemand op dezelfde VM eerlijk latency onder een milliseconde meten. Die persoon heeft niet per se ongelijk; hij kijkt simpelweg naar een andere toestand.

Een latency van nul kan verrassend weinig zeggen

Ik zag ook een iostat-interval met r_await = 0 terwijl het systeem duidelijk ongezond was: hoge iowait, processen in D-state, openstaande I/O, bijna geen afgeronde reads en vrijwel geen throughput.

Gemiddelden op basis van afgeronde operaties worden minder informatief als tijdens het meetinterval bijna niets wordt afgerond. Een nul bewijst niet noodzakelijk dat reads direct klaar waren; er kunnen simpelweg te weinig nuttige completions zijn om de vastgelopen operaties te beschrijven.

Sindsdien bekijk ik latency, IOPS, throughput, queue depth, in-flight I/O, D-state, PSI en daadwerkelijke request completion samen.

Eén incident werd een veel langer supportonderzoek

Het eerste ernstige incident overlapte met een geplande backup op de oorspronkelijke infrastructuur en FDCServers bevestigde dat die backup draaide. Dat was een redelijke kandidaatverklaring. Maar later reproduceerde ik dezelfde storage stall nadat de backup was afgelopen en buiten het oorspronkelijke backupvenster.

Het probleem keerde op meerdere dagen terug. Tijdens één incident was de VPS volgens mijn service logs vervolgens 4 uur, 41 minuten en 15 seconden niet beschikbaar. Ik kan niet bewijzen dat de storage stall zelf de VM in die toestand bracht; daarvoor was host-side informatie nodig die ik niet had.

application
    ↓
Linux VFS
    ↓
EXT4
    ↓
virtual block device
    ↓
?

Achter dat vraagteken kunnen virtualisatie, host queues, storage networking, distributed storage, fysieke media, schedulers en andere systemen zitten die voor de guest onzichtbaar zijn. Ik kon zien waar de fout zich manifesteerde, maar niet wat de fysieke root cause was.

FDCServers escaleerde het probleem intern en migreerde de VPS uiteindelijk naar een andere node. Daarna registreerde ik opnieuw een ernstige storage stall vanuit de guest. Dat bewijst niet dat alle FDCServers-nodes een storageprobleem hadden. Het bewijst alleen dat het probleem van mijn VPS vanuit mijn perspectief niet was verdwenen.

Waarom ik dit nog steeds niet als een negatief FDCServers-verhaal zie

Een infrastructuurincident verandert makkelijk in een oordeel over een hele provider. Dat wil ik hier niet doen.

Ik maak onderscheid tussen een service waarvan het normale operating model fundamenteel niet bij mijn workload past en een intermitterend infrastructuurprobleem dat moeilijk reproduceerbaar is en veel tijd kost om te isoleren. Mijn ervaring met FDCServers voelde als het tweede geval.

De VPS had vóór het incident normaal gewerkt en echt productieverkeer gedragen. Support onderzocht het probleem en probeerde het op te lossen. Uiteindelijk had ik genoeg bewijs om te besluiten dat ik productie niet langer van die specifieke VPS afhankelijk wilde maken.

Ik vroeg FDCServers om de service te annuleren en mijn geld terug te geven. Ze hebben mij terugbetaald. Dat telt mee in mijn algemene indruk.

Ik heb hun huidige infrastructuur niet opnieuw getest, dus ik kan niet zeggen hoe een FDCServers-VPS vandaag presteert. Ik heb ook geen bewijs dat mijn probleem representatief was voor hun hele fleet. Infrastructuur verandert voortdurend. Ik maak van één lastig incident op één VPS geen permanent oordeel over de provider. En ik beveel FDCServers hier ook niet aan; ik beschrijf alleen wat mij is overkomen.

Het leukste deel was Linux zelf

De downtime was frustrerend, maar het onderzoek was leuk. Ik vond het oprecht interessant om de grens van het probleem te vinden.

Ik had niet genoeg zicht om de fysieke root cause vast te stellen. De vraag waarop ik antwoord wilde was eenvoudiger: op welke laag stopt nuttig werk met afronden?

De backend antwoordde in ongeveer drie milliseconden. Nginx meldde dat het actief was, terwijl kernel stacks lieten zien dat Nginx in EXT4-reads wachtte. vmstat toonde geblokkeerde processen en extreme I/O wait. PSI liet zien dat I/O-stalls bijna de hele workload opslokten. iostat toonde enorme latency en queueing. D-state liet niet-gerelateerde processen tegelijk wachten. De kernel meldde zelfs een Nginx-task die langer dan 122 seconden geblokkeerd was.

Geen enkele metric loste het incident op. De overeenstemming tussen de signalen deed dat. Dat is een van de redenen dat ik Linux zo waardeer: je kunt beginnen met iets vaags als “mijn website opent soms niet” en stap voor stap uitkomen bij een precieze beschrijving van de laag waar nuttig werk stopt.

De debugging-workflow die ik nu gebruik

top
free -h
df -h

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

Waar mogelijk test ik ook ieder deel van het requestpad afzonderlijk:

public request
      ↓
reverse proxy
      ↓
direct backend
      ↓
filesystem
      ↓
block device

Ik vraag niet meer alleen waarom de server traag is. Ik vraag: op welke laag stopt nuttig werk met afronden? Die vraag levert veel betere experimenten op.

Een laatste regel: verzamel bewijs vóór een reboot

Een reboot kan precies zijn wat productie nodig heeft, maar kan ook de meest waardevolle diagnostische toestand wissen die je ooit te zien krijgt.

Before reboot:
D-state:     high
I/O PSI:     ~97%
iowait:      ~100%
queues:      large
requests:    failing

After reboot:
D-state:     0
latency:     milliseconds
requests:    healthy

Als beschikbaarheid en bedrijfsimpact het toelaten, leg ik eerst UTC-tijd, PSI, vmstat, iostat, D-state, wchan, kernelmeldingen, socket queues en request timings vast. Daarna herstel ik de machine.

De server draaide. De workload niet.

Ik heb nooit geleerd welk host-side component het incident uiteindelijk veroorzaakte. Ik kan niet zeggen dat een specifieke SSD defect was, geen specifieke storage node aanwijzen en niet bewijzen wat er achter het virtual block device gebeurde.

Wat ik vanuit Linux kon vaststellen was genoeg:

read latency:       up to 18.7 s
flush latency:      up to 53.6 s
I/O PSI full:       almost 100%
iowait:             almost 100%
I/O queue:          128+
Nginx:              blocked in filesystem reads
EXT4/jbd2:          blocked waiting for I/O
direct backend:     ~3 ms
HTTP through Nginx: timing out

Dat was genoeg om mijn applicatie van de falende laag te scheiden en een operationele beslissing te nemen. FDCServers betaalde de VPS terug, ik ging verder en maak van één moeilijk infrastructuurincident geen permanent oordeel over de provider.

Wat bijbleef is nuttiger: een proces kan running zijn, een service active, een VM online en ping kan werken, terwijl de machine bijna geen nuttig werk afrondt.

Linux geeft genoeg bewijs om het verschil te zien. Je moet alleen de juiste vragen stellen terwijl de storing nog aanwezig is.