Keluhan hampir selalu datang dalam bentuk kabar buruk yang kabur: “server lambat”. Tanpa prosedur, kita cenderung menebak-nebak — me-restart service, menambah RAM, mematikan proses — dan sering kali tebakan itu justru menghilangkan jejak penyebab. Troubleshooting yang baik adalah kebalikannya: pertanyaan yang tepat lebih dulu, bukti di angka dan log menyusul, satu perubahan pada satu waktu. Chapter penutup section ini merangkai semua alat dari delapan chapter sebelumnya menjadi satu prosedur urut, lalu mengujinya pada studi kasus server yang lambat setiap pagi.

Prosedur Enam Langkah #

Urutan ini memeriksa yang termurah lebih dulu, persis seperti diagnosis bottleneck di Performance Bottlenecks :

  1. Dengarkan keluhan, lalu spesifikkan. Lambat apa — login, satu halaman, atau semua service? Kapan — selalu, setiap pagi, atau sejak deploy kemarin? Siapa — satu user, satu tim, atau semua orang? Keluhan yang tetap kabur tidak bisa diverifikasi perbaikannya.
  2. Cek load average dan memori. Dua angka paling murah: uptime dibaca seperti di Uptime dan Load Average , free seperti di Memory Monitoring . Kalau keduanya sehat, pencarian langsung bergeser ke I/O dan jaringan.
  3. Identifikasi proses rakus. ps aux --sort=-%cpu | head mengurutkan proses berdasarkan CPU; top memberikan tampilan yang terus membarui — keduanya dibahas di ps, top, dan htop .
  4. Cek iowait. Load tinggi plus %wa tinggi berarti disk, bukan CPU — pembacaan lengkapnya di Disk Monitoring .
  5. Cek log pada jendela waktu keluhan. Inilah gunanya stempel waktu: saring log pada menit kejadian dengan pola grep dari Monitoring Logs .
  6. Ukur sebelum dan sesudah perbaikan. Catat angka awal sebelum menyentuh apa pun; angka yang sama diukur ulang setelah perbaikan adalah bukti satu-satunya bahwa perbaikan bekerja.

Studi Kasus: Server Lambat Pagi Hari #

Sebuah web server internal mendapat keluhan berulang: halaman dashboard lambat setiap pagi sekitar pukul 08.30, pulih sendiri sepuluh menit kemudian. Langkah pertama mempertajam keluhan: yang lambat hanya halaman dashboard yang membaca database, terjadi setiap hari kerja pukul 08.30-08.40, dialami semua user — polanya terlalu teratur untuk kebetulan.

Langkah kedua diambil saat kejadian berlangsung: uptime menunjukkan load 6.80 pada mesin dua core, sementara free masih menunjukkan ruang memori lega. Langkah ketiga memperlihatkan tiga proses berstatus D. Berikut contoh tampilan ps aux --sort=-%cpu | head -5 pada saat itu:

text
USER  PID %CPU %MEM    VSZ   RSS TTY      STAT START  TIME COMMAND
root  4101 12.3  1.1 123456 45120 ?        D    08:30  3:21 /bin/bash /usr/local/bin/backup-harian.sh
root  4102  8.1  0.9  98210 38200 ?        D    08:30  2:47 /bin/bash /usr/local/bin/kompres-log.sh
root  4110  6.7  0.7  88120 30100 ?        D    08:30  2:12 /bin/bash /usr/local/bin/sinkronisasi-data.sh
budi  5120  1.9  0.6  74310 24800 ?        Ss   08:31  0:05 sshd: budi@pts/0
www-d 5200  1.2  0.8 210430 33200 ?        S    08:31  0:02 apache2 -k start

Kolom STAT bercerita: ketiga proses teratas berstatus D — menunggu I/O, bukan menghitung. Langkah keempat mengonfirmasi: %wa 41%. Langkah kelima membawa waktu kejadian ke log; kita salin potongan log sistem pagi itu sebagai fixture cron.log, lalu saring baris perintah cron:

bash
cat > cron.log <<'AKHIR'
Jan 15 08:30:01 server-kantor CRON[4101]: (root) CMD (/usr/local/bin/backup-harian.sh)
Jan 15 08:30:01 server-kantor CRON[4102]: (root) CMD (/usr/local/bin/kompres-log.sh)
Jan 15 08:30:02 server-kantor CRON[4110]: (root) CMD (/usr/local/bin/sinkronisasi-data.sh)
Jan 15 08:31:24 server-kantor kernel: INFO task backup-harian.sh:4101 blocked for more than 120 seconds.
AKHIR
grep 'CMD' cron.log

Output yang Dihasilkan:

text
Jan 15 08:30:01 server-kantor CRON[4101]: (root) CMD (/usr/local/bin/backup-harian.sh)
Jan 15 08:30:01 server-kantor CRON[4102]: (root) CMD (/usr/local/bin/kompres-log.sh)
Jan 15 08:30:02 server-kantor CRON[4110]: (root) CMD (/usr/local/bin/sinkronisasi-data.sh)

Tiga job cron menyala di menit yang sama — dan ketiganya berat di disk: backup membaca seluruh data, kompresi menulis arsip besar, sinkronisasi mengirim semuanya keluar. Disk yang sehat menjadi jenuh dalam sepuluh menit, dan seluruh server ikut terseret. Baris keempat adalah pengakuan kernel: proses backup terblokir lebih dari 120 detik.

Perbaikannya bukan menambah hardware, melainkan menjauhkan jadwal: backup tetap pukul 08.30 (30 8 * * *), kompresi digeser ke 08.50 (50 8 * * *), sinkronisasi ke 09.10 — format field crontab dibahas tuntas di cron dan crontab , alternatif timernya di systemd Timers , dan perilaku daemon cron didokumentasikan di cron(8) . Langkah keenam dilakukan keesokan paginya: load pukul 08.30 turun ke 1.9 dan keluhan berhenti.

Praktik: Skrip Diagnosis Urut #

Prosedur di atas bisa dijalankan sebagai skrip mini yang membaca metrik dari file lalu mencetak rencana langkah berikutnya — sama seperti metrik-pagi.txt pada studi kasus tadi:

bash
cat > metrik-pagi.txt <<'AKHIR'
load1 6.80
mem 62
iowait 41
AKHIR
cat > diagnose.sh <<'AKHIR'
#!/bin/bash
# Membaca metrik dari file, mencetak rencana diagnosis berikutnya.
baca() { awk -v k="$1" '$1 == k {print $2; exit}' metrik-pagi.txt; }
load=$(baca load1); mem=$(baca mem); iowait=$(baca iowait)
echo "load=${load} mem=${mem}% iowait=${iowait}%"
if [ "$iowait" -ge 20 ]; then
  echo "1. iowait tinggi: cari proses yang menggerus disk (ps, status D)."
elif [ "$mem" -ge 90 ]; then
  echo "1. memori kritis: jalankan free -m dan cari baris OOM di log."
else
  echo "1. CPU tersangka: urutkan proses berdasar pemakaian CPU dengan top."
fi
echo "2. Cocokkan waktu keluhan dengan jejak di log sistem dan cron."
echo "3. Setelah satu perbaikan diterapkan, ukur ulang metrik yang sama."
AKHIR
bash diagnose.sh

Output yang Dihasilkan:

text
load=6.80 mem=62% iowait=41%
1. iowait tinggi: cari proses yang menggerus disk (ps, status D).
2. Cocokkan waktu keluhan dengan jejak di log sistem dan cron.
3. Setelah satu perbaikan diterapkan, ukur ulang metrik yang sama.

Mari kita bedah skrip ini baris-per-baris:

  1. Baris 3 (baca() { awk ... }): fungsi kunci-ke-nilai — awk mencari baris yang kolom pertamanya sama dengan kunci (misalnya mem), lalu mencetak kolom kedua; exit menghentikan pencarian di kecocokan pertama.
  2. Baris 4 (load=$(baca load1); ...): tiga metrik dibaca sekaligus ke dalam variabel — tiga penugasan dipisahkan titik koma dalam satu baris.
  3. Baris 6 (if [ "$iowait" -ge 20 ]): keputusan pertama jatuh ke iowait — persis urutan di chapter bottleneck, karena iowait tinggi menyamar sebagai masalah CPU; perbandingan memakai integer agar [ -ge ] aman.
  4. Baris 13-14 (echo "2. ...", echo "3. ..."): dua langkah berikutnya dicetak tanpa syarat — tersangka pertama hanyalah langkah awal, bukan vonis; jejak log dan pengukuran ulang tetap wajib.

Skrip semacam ini biasanya diberi makan angka dari uptime, free, dan vmstat — proses pengumpulannya dibahas di chapter-chapter awal section ini.

Ukur, Jangan Menebak #

Prinsip yang menutup section ini sekaligus menjadi kebiasaan seumur karier: klaim tanpa angka hanyalah opini. Baseline sebelum perbaikan, angka yang sama setelahnya, dan selisih yang bisa dijelaskan — itulah standar bukti seorang administrator. Seluruh perjalanan kita kini tersusun rapi: membaca indikator CPU, memori, disk, dan jaringan, memahami load average, menelusuri bottleneck, menyisir log, memasang batas sumber daya, dan menutupnya dengan prosedur diagnosis yang teruji. Kemampuan berikutnya bergeser dari merawat Linux ke membangun di atasnya — dimulai dari Section Development Environment yang membahas compilers dan build tools.