Debugging kısmına geçmeden önce bir şeyi netleştirmek istiyorum: FDCServers hakkında genel izlenimim olumsuz değil. Bu, insanlara sağlayıcıdan uzak durmalarını söyleyen bir inceleme değil ve tüm altyapılarının kalitesini yargılama girişimi de değil. Belirli bir dönemde kullandığım tek bir VPS'te alışılmadık derecede zor bir sorun yaşadım.
Uzun süre VPS normal çalıştı ve gerçek production trafiğini sorunsuz taşıdı. Sonra bir şey değişti. Sıradan request'ler anlamsız derecede uzun sürmeye başladı. Sayfalar önce yavaş açıldı, sonra bazen hiç açılmamaya başladı. Başka zamanlarda ise problemi düzgün inceleyemeden makine yeniden normal görünüyordu.
En kötü durumda şunları kaydettim:
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 çalışıyordu. Backend çalışıyordu. VM çevrimiçiydi. Ama neredeyse hiçbir faydalı iş ilerlemiyordu.
Production arızası can sıkıcıydı, fakat debugging sürecinin kendisi gerçekten keyifliydi. Linux'u tam da bu tür problemler yüzünden seviyorum: dışarıdan canlı görünen bir makinede birkaç bağımsız kernel arayüzü, faydalı ilerlemenin nerede durduğunu gösterebilir. Bu yazı bu işaretleri takip etmekle ilgili; FDCServers'ın iyi ya da kötü bir sağlayıcı olduğuna karar vermekle değil.
active (running) neredeyse hiçbir şey ifade etmemeye başladı
Doğal olarak temel kontrollerle başladım:
top
free -h
df -h
systemctl status nginx
Sağlıklı dönemlerde kabaca şunu görüyordum:
D-state processes: 0
CPU iowait: ~0%
disk latency: ~2–4 ms
I/O PSI some: 0.04
I/O PSI full: 0.04
Sadece böyle bir anda bağlansaydım VPS'in sağlıklı olduğu sonucuna kolayca varabilirdim. Ardından normal trafik gelir ve durum tamamen değişebilirdi. Intermittent bir sistemin sağlıklı snapshot'ı, arıza anındaki durum hakkında çok az şey söyler. Evidence'ı problem gerçekten yaşanırken toplamam gerekiyordu.
İncelemenin yönünü değiştiren iostat örneği
r_await = 18744 ms
f_await = 53561 ms
aqu-sz = 128.54
util ≈ 100%
read = 88 KB/s
Tamamlanan okumalar yaklaşık 18,7 saniye sürüyordu. Flush işlemleri yaklaşık 53,6 saniye sürüyordu. Ortalama queue 128'in üzerindeydi, buna karşılık faydalı read throughput yalnızca 88 KB/s idi.
Bu, zor bir workload'u verimli biçimde işlediği için meşgul olan storage görüntüsüne benzemiyordu. Virtual block path pratik olarak doymuştu ama çok az iş tamamlıyordu. Yüksek utilization tek başına arıza değildir; ancak devasa latency, uzun queue, stalled task'ler, düşük throughput ve başarısız request'lerle birleştiğinde bambaşka bir sinyal verir.
iowait'i tek başına diagnosis olarak kullanmayı bıraktım
blocked processes: 4–9
CPU iowait: 97–100%
CPU idle: 0%
Bunu “CPU zamanının %100'ünü diski bekleyerek geçiriyordu” diye özetlemek cazip. Sezgisel olarak faydalı olsa da Linux accounting daha karmaşıktır ve iowait diskin doğrudan ölçümü değildir. Bu nedenle onu tek bir belirti olarak ele alıp bağımsız kanıtlar aradım.
PSI, I/O'nun faydalı işi durdurduğunu gösterdi
cat /proc/pressure/io
Şiddetli bir dönemde:
some avg10=99.14
full avg10=95.55
Daha sonraki tekrar üretimlerde full %98'e yaklaştı. I/O pressure için some, en azından bazı non-idle işlerin I/O nedeniyle stalled olduğu zamanı; full ise tüm non-idle task'lerin aynı anda I/O nedeniyle stalled olduğu zamanı ifade eder. %100'e yakın bir değer yalnızca “disk meşgul” demekten çok daha fazlasıdır: workload ilerleme fırsatını neredeyse tamamen kaybetmiştir.
D-state, tek bir process'i suçlamayı bıraktırdı
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
Bir process'in kısa süre D-state'te görünmesi storage sorunu kanıtlamaz. Önemli olan hangi process'lerin birlikte bloke olduğuydu. jbd2, systemd-journald, Nginx worker'ları, Nginx cache process'leri ve başka filesystem aktiviteleri aynı anda takılıyordu.
Yalnızca backend takılırsa backend'i incelerim. Yalnızca Nginx takılırsa Nginx'i incelerim. Ancak Nginx, system journal ve EXT4 journal thread aynı anda ilerleyemiyorsa ortak dependency çok daha ilginç hale gelir. Bu durumda ortak nokta filesystem ve onun altındaki storage path idi.
Kernel stack'leri bir sonraki layer'ı gösterdi
EXT4 journal thread şu path'lerde görünüyordu:
wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction
Nginx worker'ları normal filesystem read path'lerinde görünüyordu:
folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64
Bir noktada kernel şunu raporladı:
INFO: task nginx blocked for more than 122 seconds.
systemctl status nginx hâlâ active (running) gösterebiliyordu. İki gözlem de doğruydu: process mevcuttu, fakat bir Nginx task'i iki dakikadan uzun süre faydalı işi tamamlayamamıştı. Çalışan process ile sağlıklı service aynı şey değildir.
En temiz deneyim yaklaşık üç milisaniye sürdü
Nginx üzerinden request başarısız oldu:
HTTP=000
SSL connection timeout
Ardından Nginx'i bypass edip local backend'e doğrudan bağlandım:
connect = 0.000423 s
TTFB = 0.003063 s
total = 0.003139 s
Yaklaşık 3 ms. Bu test için exact HTTP status önemli değildi. Backend connection'ı kabul ediyor, request'i çalıştırıyor ve neredeyse anında response döndürüyordu. Yaklaşık aynı anda Nginx worker'ları EXT4 read path'lerinde görünüyordu.
application execution → progressing normally
filesystem-backed web path → not progressing normally
Derine indikçe application-level açıklama daha az inandırıcı hale geldi.
Aynı VPS yaklaşık 30 saniyede çökebiliyordu
Bir reproduction öncesinde:
HTTP: 200
D-state: 0
CPU iowait: 3%
r_await: ~1.18 ms
I/O PSI full: ~2.95%
Yaklaşık yarım dakika sonra:
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
Daha sonra:
CPU iowait: 96–100%
I/O PSI full: ~98%
HTTPS queue: 512
HTTP: 000
Workload'u kaldırdığımda ters geçiş hızlı gerçekleşebiliyordu:
D-state: 0
CPU iowait: 6%
r_await: ~0.98 ms
queue depth: ~0.07
HTTP: 200
Intermittent altyapı arızalarının zor olmasının nedeni bu. On dakika sonra başka biri aynı VM'de sub-millisecond latency ölçebilir ve tamamen doğru söyleyebilir. Hatalı olmak zorunda değildir; yalnızca farklı bir state'e bakıyordur.
Sıfır latency şaşırtıcı biçimde faydasız olabilir
Sistem açıkça sağlıksızken iostat içinde r_await = 0 gördüğüm bir interval da oldu: yüksek iowait, D-state process'leri, outstanding I/O, neredeyse hiç tamamlanan read yok ve throughput neredeyse sıfır.
Tamamlanan işlemlere dayanan ortalamalar, sampling interval içinde neredeyse hiçbir şey tamamlanmadığında daha az bilgi verir. Sıfır değeri read'lerin anında bittiğini kanıtlamaz; takılı kalan operasyonları tanımlayacak yeterli completion olmayabilir.
Bu incident'ten sonra latency, IOPS, throughput, queue depth, in-flight I/O, D-state, PSI ve gerçek request completion'ı birlikte incelemeye başladım.
Bir incident çok daha uzun bir support incelemesine dönüştü
İlk ağır olay, orijinal altyapıdaki scheduled backup ile çakıştı ve FDCServers backup'ın çalıştığını doğruladı. Başlangıçta makul bir açıklama adayıydı. Ancak backup tamamlandıktan ve orijinal backup window dışına çıkıldıktan sonra aynı storage stall sınıfını tekrar ürettim.
Problem farklı günlerde geri geldi. Bir incident sırasında VPS daha sonra service log'larıma göre 4 saat 41 dakika 15 saniye erişilemez durumda kaldı. Storage stall'ın VM'i bu state'e soktuğunu kanıtlayamam; bunun için bende olmayan host-side bilgi gerekirdi.
application
↓
Linux VFS
↓
EXT4
↓
virtual block device
↓
?
Soru işaretinin arkasında virtualization, host queues, storage networking, distributed storage, fiziksel medya, schedulers ve guest tarafından görünmeyen başka sistemler olabilir. Failure'ın nerede ortaya çıktığını görebiliyordum, fiziksel root cause'u değil.
FDCServers konuyu içeride escalate etti ve sonunda VPS'i başka bir node'a migrate etti. Migration sonrasında guest tarafında başka bir ağır storage stall daha yakaladım. Bu, tüm FDCServers node'larında storage problemi olduğunu kanıtlamaz. Yalnızca benim açımdan VPS'imi etkileyen problemin ortadan kalkmadığını gösterir.
Neden bunu yine de FDCServers hakkında olumsuz bir hikâye olarak görmüyorum
Tek bir altyapı incident'ini tüm provider hakkında hükme dönüştürmek kolaydır. Ben bunu yapmak istemiyorum.
Normal operating model'i workload'uma temelden uymayan bir service ile intermittent, yeniden üretmesi zor ve izole edilmesi uzun süren bir infrastructure problem arasında fark var. FDCServers deneyimim ikinci duruma daha yakındı.
Incident öncesinde VPS normal çalışmış ve gerçek production trafiğini taşımıştı. Support problemi araştırdı ve çözmeye çalıştı. Sonunda production'ın o belirli VPS'e bağlı kalmasını istemediğime karar verecek kadar evidence toplamıştım.
Service'i iptal etmelerini ve refund istedim. FDCServers paramı iade etti. Bu, genel izlenimim açısından önemlidir.
Mevcut altyapılarını yeniden test etmedim; dolayısıyla bugün bir FDCServers VPS'in nasıl davrandığını söyleyemem. Benim instance'ımda yaşananların tüm fleet'i temsil ettiğine dair de kanıtım yok. Infrastructure sürekli değişir. Bir VPS'teki zor bir incident'i tüm provider hakkında kalıcı bir yargıya dönüştürmem. Burada FDCServers'ı tavsiye de etmiyorum; yalnızca başıma geleni anlatıyorum.
En çok hoşuma giden kısım Linux'un kendisiydi
Downtime can sıkıcıydı, ancak investigation eğlenceliydi. Problemin sınırını bulmaktan gerçekten keyif aldım.
Fiziksel root cause'u belirleyecek kadar visibility'ye sahip değildim. Cevabını aradığım soru daha basitti: faydalı iş hangi layer'da tamamlanmayı bırakıyor?
Backend yaklaşık üç milisaniyede yanıt veriyordu. Nginx active görünüyordu ama kernel stack'leri EXT4 read içinde beklediğini gösteriyordu. vmstat blocked process'leri ve aşırı I/O wait'i gösterdi. PSI, I/O stall'ların workload'un neredeyse tamamını tükettiğini gösterdi. iostat çok büyük latency ve queueing gösterdi. D-state birbiriyle ilgisiz process'lerin birlikte beklediğini gösterdi. Kernel, 122 saniyeden uzun süredir blocked bir Nginx task'i bile raporladı.
Tek bir metric incident'i çözmedi. Bağımsız sinyallerin aynı şeyi göstermesi çözdü. Linux'u sevme nedenlerimden biri de bu: “site bazen açılmıyor” gibi belirsiz bir problemle başlayıp faydalı işin hangi layer'da durduğunu oldukça kesin biçimde gösterebilirsiniz.
Şimdi kullandığım debugging workflow
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
Mümkün olduğunda request path'in her bölümünü ayrı ayrı test ediyorum:
public request
↓
reverse proxy
↓
direct backend
↓
filesystem
↓
block device
Artık yalnızca “server neden yavaş?” diye sormuyorum. Faydalı iş hangi layer'da tamamlanmayı bırakıyor? diye soruyorum. Bu soru çok daha iyi deneyler üretiyor.
Son bir kural: reboot etmeden önce evidence toplayın
Reboot production'ın tam olarak ihtiyaç duyduğu şey olabilir, ama görebileceğiniz en değerli diagnostic state'i de silebilir.
Before reboot:
D-state: high
I/O PSI: ~97%
iowait: ~100%
queues: large
requests: failing
After reboot:
D-state: 0
latency: milliseconds
requests: healthy
Availability ve iş etkisi izin veriyorsa önce UTC timestamp, PSI, vmstat, iostat, D-state, wchan, kernel mesajları, socket queue'ları ve request timings'i kaydediyorum. Sonra makineyi kurtarıyorum.
Server çalışıyordu. Workload çalışmıyordu.
Sonunda hangi host-side component'in incident'e yol açtığını hiçbir zaman öğrenemedim. Belirli bir SSD'nin bozulduğunu söyleyemem, belirli bir storage node'u işaret edemem ve virtual block device'ın arkasında ne olduğunu kanıtlayamam.
Linux içinden doğrulayabildiğim şeyler yeterliydi:
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
Application'ı arızalı layer'dan ayırmaya ve operasyonel karar vermeye yetti. FDCServers VPS ücretini iade etti, ben devam ettim ve tek bir zor infrastructure incident'ini provider hakkında kalıcı bir hükme dönüştürmedim.
Bende kalan daha faydalı ders şu oldu: process running olabilir, service active olabilir, VM online olabilir, ping çalışabilir; yine de makine neredeyse hiç faydalı iş tamamlamıyor olabilir.
Linux bu farkı görmek için yeterince evidence verir. Sadece failure hâlâ ortadayken doğru soruları sormak gerekir.