Ubuntu Sunucu Neden Yavaş: Performans Sorunları ve Çözümleri
Bir gece yarısı telefon zili. “Sunucu çok yavaş, kullanıcılar bağlanamıyor.” Bu sahneyi yaşamayan sysadmin var mı? Ben bu tür aramaları yıllar içinde o kadar çok aldım ki artık uyku düzenim buna göre şekillendi. Sabah 3’te gözlerimi ovuştura ovuştura SSH açmak, top çıktısına bakmak, nerede sorun var diye avlamak… Evet, tam olarak o deneyimden bahsedeceğim bu yazıda.
Ubuntu sunucu performans sorunları genellikle birkaç ana kategoriye giriyor: CPU baskısı, bellek sıkışması, disk I/O tıkanıklığı ve ağ sorunları. Bunların her biri kendi içinde farklı semptomlar veriyor ve teşhis yöntemi de farklılaşıyor. Tek tek ele alalım, ama önce genel tanı araçlarından başlayalım.
İlk Müdahale: Ne Olduğunu Anlamak
Sunucuya bağlandığınızda ilk yapacağınız şey sisteme genel bir bakış atmak. Panikle top açıp oradan oraya tıklamak yerine, sistematik bir yaklaşım benimseyin.
# Sistem yükünü ve çalışma süresini görün
uptime
# Anlık kaynak kullanımı
vmstat 1 5
# CPU, bellek, swap, I/O özeti
dstat -cdngy --top-cpu --top-mem 5 10
uptime çıktısındaki load average değerleri size çok şey söyler. Tek çekirdekli bir sistemde bu değer 1’in üzerine çıkıyorsa sorun var. 8 çekirdekli bir sistemde 8’in üzerindeyse yine sorun var. Kural basit: load average değeri, sistemdeki toplam çekirdek sayısını geçmemeli.
vmstat çıktısında dikkat etmeniz gereken birkaç sütun var. r sütunu çalışmayı bekleyen process sayısını gösterir. Bu değer çekirdek sayısını sürekli aşıyorsa CPU tıkanıklığınız var. b sütunu ise I/O bekleyenleri gösterir, bu değer yüksekse disk sorununuz var demektir.
CPU Kaynaklı Yavaşlamalar
CPU sorunlarında en kötü senaryo, bir processin çıldırıp tüm kaynakları yutmasıdır. Bunu bulmak için:
# CPU kullanımına göre sıralı process listesi
ps aux --sort=-%cpu | head -20
# Hangi process en çok CPU yiyor, 3 saniyede bir güncelle
watch -n 3 'ps aux --sort=-%cpu | head -10'
# Belirli bir processin ne yaptığını izle
strace -p <PID> -c
Bir keresinde bir müşteri sunucusunda PHP-FPM worker’ları delirip her biri %100 CPU kullanıyordu. ps aux çıktısında 50’den fazla PHP process’i görünce durumu anladım. Sorun PHP kodunda sonsuz bir döngüydü ama bunu bulmak için önce sistemi stabilize etmek gerekti.
CPU throttling sorununa da dikkat edin. Özellikle cloud ortamlarında burstable instance’larda CPU kredisi tükenince sistem dramatik biçimde yavaşlar. AWS t2/t3 veya Azure B serisi kullanıyorsanız bunu kontrol edin.
# CPU frekansını kontrol et
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
# CPU istatistiklerini detaylı gör
mpstat -P ALL 1 5
mpstat çıktısında %iowait değeri yüksekse problem CPU’dan değil, diskten kaynaklanıyor olabilir. Bu önemli bir ayrım, çünkü teşhis ve çözüm tamamen farklılaşır.
Kernel ve Process Scheduling
Bazen sorun belirli bir process değil, scheduling politikasıdır. Özellikle birçok küçük işlem yapan sistemlerde context switch sayısı aşırı yükselir:
# Context switch sayısını izle
vmstat 1 | awk '{print $12, $13}'
# Detaylı kernel istatistikleri
perf stat -a sleep 5
Context switch sayısı saniyede birkaç on bini geçmeye başlıyorsa, uygulamanızın mimarisini gözden geçirmeniz gerekebilir.
Bellek Sorunları: OOM Killer’ın Gelmesi
Bellek sorunları sinsi yavaşlamalara yol açar. Sistem swapa düşmeye başladığında her şey ağır çekim gibi çalışır. Önce mevcut durumu anlayalım:
# Bellek kullanım özeti
free -h
# Detaylı bellek istatistikleri
cat /proc/meminfo
# Hangi processler en çok bellek kullanıyor
ps aux --sort=-%mem | head -20
# OOM Killer devreye girdi mi diye kontrol et
dmesg | grep -i "oom|out of memory" | tail -20
free -h çıktısında available sütununa bakın, free sütununa değil. Linux belleği cache olarak kullandığı için “free” değeri düşük görünebilir, bu normal. Asıl sorun “available” değerinin kritik seviyelere düşmesi.
Swap kullanımı başladığında ne yapmalısınız? İlk önce hangi processin belleği yuttuğunu bulun:
# Bellek kullanımını process bazında izle
smem -r -s rss | head -20
# Swap kullanan processler
for pid in /proc/[0-9]*/status; do
awk '/VmSwap|Name/{printf $2 " "}END{print ""}' $pid
done | sort -k2 -n -r | head -20
MySQL veya PostgreSQL çalıştırıyorsanız, veritabanı buffer pool ayarlarını gözden geçirin. Çok yaygın bir hata: MySQL’in innodb_buffer_pool_size değerini sunucu RAM’inin %80’ine set etmek, ardından başka servisler için yer kalmadığını görmek. Bu ayarı %60-70 civarında tutmak genellikle daha sağlıklı.
Swappiness Ayarı
# Mevcut swappiness değerini öğren
cat /proc/sys/vm/swappiness
# Geçici olarak değiştir (sunucu veritabanı veya uygulama sunucusuysa)
sysctl vm.swappiness=10
# Kalıcı hale getir
echo 'vm.swappiness=10' >> /etc/sysctl.conf
sysctl -p
Varsayılan swappiness değeri 60’tır. Bu, bellek dolmadan çok önce sistemi swapa itmek demek. Uygulama veya veritabanı sunucuları için bu değeri 10 veya daha düşük tutun. Yine de 0 yapmayın, sistem beklenmedik anlarda tamamen cevap vermez hale gelebilir.
Disk I/O: Sessiz Katil
Disk I/O sorunları genellikle CPU yükü yüksek görünmesine rağmen processler aslında hiçbir şey yapmadan disk beklerken ortaya çıkar. Bu durumda top çıktısında wa (I/O wait) değeri yüksek görünür.
# Disk I/O istatistiklerini izle
iostat -xz 1 5
# Hangi process en çok disk I/O yapıyor
iotop -o -b -n 5
# Disk latency kontrolü
ioping -c 20 /var/log/
iostat çıktısında dikkat etmeniz gereken değerler:
- %util: Diskin meşgul olduğu sürenin yüzdesi. %80’in üzerindeyse disk doyma noktasına yaklaşıyor
- await: Ortalama I/O bekleme süresi (ms). SSD için 1-5ms normal, HDD için 5-20ms kabul edilebilir
- svctm: Servis süresi. await ile arasındaki fark çok büyükse kuyruk oluşuyor demektir
Çok sık karşılaştığım bir senaryo: log dosyaları kontrolsüz büyüyor, disk dolar, sistem yavaşlar. Basit ama etkili kontrol:
# Büyük dosyaları bul
find / -type f -size +100M -exec ls -lh {} ; 2>/dev/null | sort -k5 -rh | head -20
# En çok yer kaplayan dizinler
du -sh /* 2>/dev/null | sort -rh | head -10
# İnodes kullanımını kontrol et (çok küçük dosya problemi)
df -i
Inode dolması gerçek bir sorun. Disk alanı var ama inode bitti mi? Sistem yeni dosya oluşturamaz ve bu garip hatalar üretir. Özellikle mail sunucusu veya temp dosyaları çok oluşturan sistemlerde görülür.
Dosya Sistemi ve Mount Seçenekleri
# Mevcut mount seçeneklerini gör
cat /proc/mounts
# Ext4 için atime güncellemesini kapat (okuma performansını artırır)
# /etc/fstab dosyasında ilgili satıra noatime ekleyin
# Örnek: /dev/sda1 / ext4 defaults,noatime 0 1
# Disk scheduler'ı kontrol et (SSD için none veya mq-deadline önerilir)
cat /sys/block/sda/queue/scheduler
# SSD için scheduler değiştir
echo mq-deadline > /sys/block/sda/queue/scheduler
noatime mount seçeneği özellikle okuma yoğun sistemlerde ciddi performans farkı yaratır. Her dosya okunduğunda access time güncellemesi yazma işlemi gerektirir. Bunu kapatmak gereksiz write operasyonlarını azaltır.
Ağ Performans Sorunları
Ağ sorunları en yanıltıcı olanlar. Sistem kendi kaynakları açısından sağlıklı görünür ama yavaş çalışır. Başlangıç noktası:
# Ağ arayüzü istatistikleri
ip -s link show
# Aktif bağlantılar ve durumları
ss -s
# Hangi process hangi portu kullanıyor, bağlantı sayılarıyla
ss -tnp | awk 'NR>1 {print $5, $6}' | sort | uniq -c | sort -rn | head -20
# Ağ gecikmesi testi
ping -c 100 <hedef_ip> | tail -5
ss -s çıktısında TIME-WAIT bağlantısı sayısı binleri geçiyorsa, TCP stack ayarlarınızı gözden geçirmeniz gerekiyor. Özellikle yüksek trafik alan web sunucularında bu kritik:
# TCP ayarlarını optimize et
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
EOF
sysctl -p
Dikkat: tcp_tw_recycle parametresini internete bakan sunucularda açmayın. NAT arkasındaki istemcilerden gelen paketleri droplar ve bu gerçek bir baş ağrısı olur. tw_reuse ile tw_recycle arasındaki farkı iyi anlayın.
DNS Gecikmesi
Bazen sorun ne CPU, ne bellek, ne de disk. Sadece yavaş DNS resolution. Özellikle her istek için hostname çözümleme yapan uygulamalarda bu kritik:
# DNS çözümleme süresini ölç
time dig google.com @8.8.8.8
# nsswitch konfigürasyonunu kontrol et
cat /etc/nsswitch.conf
# DNS cache durumu (systemd-resolved kullanıyorsanız)
systemd-resolve --statistics
/etc/hosts dosyasına sık kullanılan adresleri eklemek, local DNS cache kurmak veya nscd kullanmak bu sorunu çözer.
Servis ve Uygulama Bazlı Teşhis
Altyapı seviyesinde sorun yoksa, servis bazına inmeniz gerekir. Systemd ile çalışan bir sistemde:
# En çok kaynak kullanan servisleri listele
systemd-cgtop
# Belirli bir servisin kaynak kullanımını izle
systemctl status nginx --no-pager -l
# Systemd service logları (hata ve uyarılar)
journalctl -u nginx --since "1 hour ago" -p err
# Tüm servislerin başlangıç sürelerini gör
systemd-analyze blame | head -20
systemd-analyze blame boot süresini optimize etmek için de kullanılır ama aynı zamanda hangi servislerin genel olarak yavaş olduğunu anlamak için de çıktısı ipucu verir.
Nginx/Apache Performans Kontrolü
Web sunucusu çalıştırıyorsanız, worker ve connection ayarları kritik:
# Nginx bağlantı durumu (stub_status aktifse)
curl -s http://localhost/nginx_status
# Apache server status
curl -s http://localhost/server-status?auto
# Aktif connection sayısını izle
watch -n 2 'ss -tnp | grep :80 | wc -l'
Sistematik Performans Profili Çıkarma
Tek seferlik teşhis yetmez. Uzun vadeli performans sorunlarını yakalamak için baseline oluşturun:
# Sar ile sistem istatistiklerini kaydet (sysstat paketi gerekli)
apt install sysstat -y
# /etc/default/sysstat dosyasında ENABLED="true" yapın
# Ardından servisi başlatın
systemctl enable sysstat
systemctl start sysstat
# Geçmiş CPU kullanımını görüntüle
sar -u 1 10
# Geçmiş bellek kullanımı
sar -r 1 10
# Geçmiş I/O
sar -d 1 10
# Dünün tüm raporunu görüntüle
sar -A -f /var/log/sysstat/sa$(date -d yesterday +%d)
sysstat paketi sisteminizin geçmişini tutar. Bir performans sorunu yaşandığında “tam o sırada ne oluyordu” sorusunu cevaplamanızı sağlar. Bu kurulmamışsa, sorun anında ne olduğunu hiçbir zaman tam olarak bilemezsiniz.
Hızlı Teşhis Script’i
Birden fazla sistemi yönetiyorsanız, her sunucuya bağlandığınızda hızlı genel bakış sağlayan küçük bir script işinizi kolaylaştırır:
#!/bin/bash
# /usr/local/bin/syscheck.sh
echo "=== SYSTEM HEALTH CHECK ==="
echo "Tarih: $(date)"
echo ""
echo "--- Uptime & Load ---"
uptime
echo ""
echo "--- Memory ---"
free -h
echo ""
echo "--- Disk ---"
df -h | grep -v tmpfs
echo ""
echo "--- Top CPU Processes ---"
ps aux --sort=-%cpu | head -6
echo ""
echo "--- Top MEM Processes ---"
ps aux --sort=-%mem | head -6
echo ""
echo "--- Recent OOM Events ---"
dmesg --time-format=reltime | grep -i "oom|killed process" | tail -5
echo ""
echo "--- Failed Services ---"
systemctl list-units --state=failed --no-legend 2>/dev/null | head -10
Bu script’i sunucuya bağlandığınızda otomatik çalıştırmak için .bashrc veya .bash_profile dosyasına ekleyebilirsiniz.
Kernel Parametreleri ve Sistem Sınırları
Açık dosya limitleri ve ulimit değerleri sıkça göz ardı edilir. Yüksek bağlantı sayısı olan servislerde “too many open files” hatası performans sorunlarına yol açar:
# Sistem geneli limitleri kontrol et
ulimit -a
# Açık dosya sayısını kontrol et
lsof | wc -l
# Belirli bir processin açık dosya limiti
cat /proc/<PID>/limits
# Sistem geneli max open files
sysctl fs.file-max
# Kalıcı limit artırımı için /etc/security/limits.conf
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
Systemd ile çalışan servisler için limits.conf yeterli olmayabilir. Servisin unit dosyasına da eklemeniz gerekir:
# Servis unit dosyasını düzenle
systemctl edit nginx
# Açılan dosyaya ekle:
[Service]
LimitNOFILE=65535
# Reload et
systemctl daemon-reload
systemctl restart nginx
Sonuç
Performans sorunları genellikle tek bir nedene bağlı değil. Birden fazla faktör bir araya gelince sistem yavaşlar. Bu yüzden “CPU mu sorunlu, disk mi?” diye tek bir şeye odaklanmak yerine bütüncül bir yaklaşım benimseyin.
Birkaç temel kural aklınızda kalsın: Önce ölç, sonra yorum yap. Hislerinize güvenmeyin, sayılara bakın. vmstat, iostat, sar ve ss bu konuda en güvenilir arkadaşlarınız.
Baseline olmadan anomali anlaşılmaz. Sysstat kurulumu basit bir işlem ama yokluğunda kriz anında kör uçuş yaparsınız. Kurulu değilse bu yazıyı okumayı bırakın ve şu an kurun.
Geçici fix’leri belgelendirin. Gece yarısı sysctl ile bir şeyleri değiştirdiniz, sabah uyandınız, unuttunuz. Kalıcı hale getirmeyi unutmayın, değişikliklerinizi not edin.
Son olarak: her performans sorununun bir hikayesi var. Sistem size söylemeye çalışıyor ama dinlemeyi bilmek gerekiyor. Araçlar sadece bu dili çevirmenize yardımcı oluyor. Ne kadar çok sorun çözerseniz, sistem size o kadar net konuşmaya başlıyor. Sabır ve sistematik yaklaşım, her seferinde sizi doğru cevaba götürür.
