Site yavaşladığında Linux sunucuda sorunun CPU, bellek, disk, ağ ya da uygulama kaynaklı olduğunu beş dakikada ayırt etmeyi sağlayan 10 komut.
Telefon çalıyor: “Site çok yavaş.” İlk refleks sunucuyu yeniden başlatmaktır ve itiraf edeyim, çoğu zaman işe de yarar. Ama yeniden başlatma sorunu çözmez, sadece delilleri siler. Yarım saat sonra aynı telefon yine çalar.
Bu yazı, benim yavaşlayan bir sunucuda sırayla baktığım 10 komut. Amaç sorunu hemen çözmek değil, önce nerede olduğunu bulmak. Sunucu yavaşlığının dört olağan şüphelisi var: işlemci, bellek, disk ve ağ. Beşincisi de genellikle uygulamanın kendisi.
Kısa cevap: uptime ile yükü, top ile işlemci ve bekleme sürelerini, free ve vmstat ile belleği, df ve iostat ile diski, ss ile bağlantıları, journalctl ve dmesg ile hataları kontrol et. Sonra uygulamanın kendi loglarına geç.
1. uptime: ne kadar yüklüyüz?
uptime
nproc
Sondaki üç sayı son 1, 5 ve 15 dakikanın yük ortalaması. Bu sayıyı çekirdek sayısıyla (nproc) karşılaştır. 4 çekirdekli bir sunucuda 4 civarı “dolu ama idare ediyor”, 12 ise “kuyruk kapıya dayandı” demek. Üç sayının sırası da bir şey anlatır: 1 dakikalık değer 15 dakikalıktan çok yüksekse sorun yeni başlamış.
Linux’ta bir incelik var: yük ortalaması, diski bekleyen süreçleri de sayar. Yük yüksek ama işlemci boştaysa, suçlu büyük ihtimalle disk.
2. top (ya da htop): kim yiyor?
top açıldığında üstteki %Cpu(s) satırında üç değere bak:
us: uygulamaların harcadığı işlemci. Yüksekse PHP, Node ya da veritabanı çok çalışıyor.wa: diski bekleyerek geçen süre. Yüksekse işlemci değil disk yetişemiyor.st: “steal”, yani sanal sunucuda başka müşterilerin senden aldığı işlemci. Bu değer sürekli yüksekse kod değil, komşu sorunu yaşıyorsun. Sağlayıcıyla konuşma zamanı.
top içindeyken P işlemciye, M belleğe göre sıralar.
3. free -h: bellek gerçekten bitti mi?
free -h
Buradaki klasik yanlış anlama: free sütunu küçük görünür ve insanlar paniğe kapılır. Linux boştaki belleği disk önbelleği için kullanır ve gerektiğinde geri verir. Bakman gereken sütun available. O da küçükse ve swap doluyorsa, bellek gerçekten dar.
4. vmstat: bellek ve disk nabzı
vmstat 1 5
Saniyede bir, beş satır. si ve so sütunları swap’tan okuma ve swap’a yazma. Bunlar sürekli sıfırdan büyükse sunucu RAM yetmediği için diske taşıyor ve her şey sürünüyor. r sütunu işlemci sırası bekleyen süreç sayısı; çekirdek sayısını sürekli aşıyorsa işlemci yetmiyor.
5. df: disk dolu mu?
df -h
df -i
Disk yüzde yüz dolunca veritabanı yazamaz, oturumlar açılamaz, loglar kesilir ve site çok garip şekillerde bozulur. İkinci komut daha az bilinir: diskte yer olsa bile inode biterse yeni dosya oluşturulamaz. Temizlenmeyen PHP oturum dosyaları ya da on binlerce küçük önbellek dosyası buna yol açabilir.
Neyin yer kapladığını bulmak için:
sudo du -xh / --max-depth=1 | sort -h
Bir tuzak daha: silinmiş ama hâlâ bir süreç tarafından açık tutulan dosyalar yer kaplamaya devam eder. Büyük bir log dosyasını sildin ama disk boşalmadıysa:
sudo lsof +L1
Dosyayı tutan servisi yeniden başlatınca yer geri gelir.
6. iostat: disk yetişiyor mu?
sysstat paketiyle gelir:
iostat -xz 1
%util sürekli 100’e yakınsa ve r_await ya da w_await onlarca milisaniyeyse disk darboğaz. Hangi sürecin diski kullandığını görmek için sudo iotop işe yarar. Gece 03.00’te çalışan yedek betiği ile gündüz çalışan yedek betiği arasındaki fark çoğu zaman buradan görünür.
7. ss: kaç bağlantı var, kimden?
ss -s
ss -tn state established '( sport = :443 )' | wc -l
Birincisi özet, ikincisi 443 portundaki açık bağlantı sayısı. Normalde 50 olan sayı 2000’e çıktıysa ya çok iyi bir kampanya yaptın ya da biri seni tarıyor. Hangisi olduğunu web sunucusu logu söyler:
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
Tek bir IP binlerce istek atıyorsa bu ziyaretçi değil, bot.
8. journalctl: sistem ne diyor?
sudo journalctl -p err -b
sudo journalctl -u nginx --since "1 hour ago"
İlki bu açılıştan beri kaydedilen hatalar, ikincisi belirli bir servisin son bir saati. nginx yerine php8.3-fpm ya da mysql gibi kendi servis adını yaz.
9. dmesg: çekirdek birini öldürdü mü?
sudo dmesg -T | grep -iE "out of memory|killed process"
Bellek biterse çekirdeğin “OOM killer” adlı mekanizması bir süreci öldürür. Veritabanı “kendiliğinden” kapanıyorsa ilk bakılacak yer burası. Bu satırı görürsen sorun bellek; ya uygulamanın bellek ayarları fazla cömert ya da sunucu küçük.
10. Uygulamanın kendisi
Sistem tarafı temiz çıktıysa sıra uygulamada. En sık gördüğüm iki şüpheli:
- Veritabanı: MySQL veya MariaDB’de
SHOW FULL PROCESSLIST;o anda çalışan sorguları gösterir. Aynı sorgu onlarca kez, uzun süredir bekliyorsa eksik bir indeks bulmuşsun demektir. Kalıcı çözüm için yavaş sorgu logunu (slow_query_log) aç. - PHP-FPM: logunda
server reached pm.max_children settingsatırı varsa PHP işçileri yetmiyor ve istekler sırada bekliyor. Bu ayarın nasıl hesaplanacağı ayrı bir yazının konusu.
Beş dakikalık sıra
Panik anında hatırlamak için:
uptime: yük var mı?top: işlemci mi (us), disk mi (wa), komşu mu (st)?free -hvevmstat 1 5: bellek ve swapdf -h,df -i,iostat -xz 1: diskss -sve erişim logu: trafikjournalctl,dmesg: hatalar- Veritabanı ve PHP-FPM logları: uygulama
Son bir tavsiye: bu komutları sunucu sağlıklıyken de bir kez çalıştır ve normal değerleri not al. “Yük 3” iyi mi kötü mü, ancak normalde kaç olduğunu biliyorsan anlarsın.
Sunucuyu baştan doğru kurmak için yeni bir Linux sunucuda ilk 30 dakika yazısına da göz atabilirsin.