İçeriğe Atla
Mustafa Erbay
Kariyer İnsan tarafından yazıldı · 11 dk okuma · görüntülenme Read in English
100%

Kendi VPS Krizim: Müşteri Toplantısında Gelen O Anlık Panik

Müşteri toplantısında kritik bir anda VPS'imin çökmesiyle yaşadığım panik ve çözüm sürecini paylaşıyorum. Teknik detaylar ve dersler.

Bir sunucu odasında panik içinde klavyeye bakan bir kişinin silüeti.

Müşteri Toplantısında Gelen O Anlık Panik

Geçen salı sabahı saat 10:00 civarıydı. Tam bir müşteriyle canlı yayında sunum yaparken, siteden bir bildirim sesi geldi. Göz ucuyla ekrana baktığımda, monitörümde çalışan bir servis artık yanıt vermiyordu. O anda hissettiğim o soğuk ter, sanırım kariyerim boyunca unutamayacağım anlardan biri olacak. Aylardır üzerinde çalıştığımız büyük bir proje için kritik bir demo yapıyorduk ve tam en önemli noktaya gelmişken, kendi VPS’imdeki bir servis çöküvermişti.

Bu tür durumlar, özellikle sahada uzun yıllar geçirmiş biri olarak bana yabancı değil. Ancak bu seferki farklıydı; çünkü olayın merkezinde ben vardım ve bir yandan da sunumu bırakmadan durumu kurtarmaya çalışıyordum. Müşteriye dönüp “Bir saniye, sistemde bir problem yaşıyoruz” demek yerine, hızlıca panik butonuna basmadan olayı çözmeye odaklanmam gerekiyordu. Bu yazı, o gün yaşadığım krizi, nasıl bir yol izlediğimi ve bu tür durumlarla başa çıkmak için neler öğrendiğimi anlatıyor.

Kriz Anının Detayları: Ne Oldu da Böyle Oldu?

Toplantı sırasında ne olduğunu tam olarak anlamam birkaç saniye sürdü. Siteden gelen bildirim, nginx’in artık backend uygulamama trafik yönlendirmediğini gösteriyordu. Müşterinin gözleri ekrandaydı, konuşmamı bekliyordu. Ben ise bir yandan konuşmaya devam ederken, bir yandan da gözümle terminaldeki systemctl status myapp komutunun çıktısını arıyordum. Ve işte orada, “Active: failed (result=oom-killer)” yazısını gördüm.

Bu çıktı, tahmin edebileceğiniz gibi hiç iyi bir haber değildi. Uygulamamın belleği o kadar tüketmişti ki, çekirdek onu otomatik olarak kapatmıştı. Müşteriyle yaptığım görüşme, aslında bir acil durum müdahalesi (incident response) senaryosuna dönüşmüştü. O an, “keşke bu sunucuda daha fazla RAM olsaydı” diye düşünmek yerine, “şu an bu durumu nasıl toparlarım?” sorusuna odaklanmak zorundaydım.

Durum Tespiti ve İlk Müdahaleler

Toplantıyı mümkün olduğunca kesmemeye çalışarak, hızlıca bir kaç komut çalıştırdım. İlk olarak dmesg çıktısına baktım. Bu komut, çekirdek mesajlarını gösterir ve OOM Killer’ın ne zaman ve neden tetiklendiği hakkında detaylı bilgi verir. Çıktıda, uygulamamın PID’ini ve ne kadar bellek tükettiğini açıkça görüyordum. Yaklaşık 3.5 GB RAM kullanıyordu. Bu, normalde benim VPS’im için oldukça yüksek bir değerdi.

Ardından, top komutuyla anlık bellek kullanımını kontrol ettim. Gördüğüm manzara şuydu: myapp süreci, beklediğimden çok daha fazla bellek kullanıyordu. Normalde bu kadar bellek tüketmemesi gerekiyordu. Acaba bir hafıza sızıntısı (memory leak) mı vardı, yoksa son gelen güncelleme mi soruna yol açmıştı? Müşteriyle konuşurken bir yandan da htop ile detaylı inceleme yapıyordum.

Kapanan Uygulamayı Yeniden Başlatmak

İlk önceliğim, uygulamayı tekrar ayağa kaldırmaktı. systemctl restart myapp komutuyla uygulamayı yeniden başlattım. Bu komut, OOM Killer tarafından kapatılan süreci tekrar başlatır. Birkaç saniye sonra systemctl status myapp komutuyla kontrol ettiğimde, uygulamanın active (running) olduğunu gördüm. Bu, toplantının o kritik anını kurtarmamı sağladı. Müşteriye “Evet, sanırım sorunu giderdik” derken, içten içe derin bir nefes aldım.

Ancak bu geçici bir çözümdü. Sorunun kök nedenini bulmam ve kalıcı bir çözüm üretmem gerekiyordu. Aksi takdirde, bir sonraki toplantıda ya da daha da kötüsü, canlıda büyük bir sorunla karşılaşabilirdim. Kendi VPS’imde çalışıyor olmamın en büyük avantajı, bu tür durumları istediğim zaman inceleyebilmemdi. Müşteriyle olan görüşmem bittikten sonra hemen derinlemesine analize başladım.

Kök Neden Analizi: Bellek Sızıntısı mı, Yoksa Başka Bir Şey mi?

Toplantı biter bitmez, VPS’ime SSH ile bağlandım. İlk işim, OOM Killer’ın tetiklendiği anla ilgili logları daha detaylı incelemek oldu. journalctl -xe komutuyla sistem loglarına baktığımda, uygulamamın özellikle belli bir işlem sırasında aşırı bellek tükettiğini fark ettim. Bu işlem, gelen verileri işleyen bir API endpoint’iydi.

Uygulamam Node.js tabanlı olduğu için, Node.js’in bellek yönetimi ve çöp toplama (garbage collection) mekanizmalarını da gözden geçirdim. V8 JavaScript engine’inin bellek kullanımını izlemek için process.memoryUsage() gibi araçları kullanmaya başladım. Bu araçlar, uygulamanın heap kullanımını ve toplam bellek tüketimini gerçek zamanlı olarak gösterir.

Astro Build OOM Deneyimimden Dersler

Bu olay bana, yaklaşık bir ay önce Astro projemle yaşadığım bir durumu hatırlattı. Astro’nun build süreci de zaman zaman yüksek bellek tüketebiliyordu. O zamanlar, build işlemi sırasında sistem belleğinin %90’ını kullanan ve sonunda OOM-killed olan bir süreçle karşılaşmıştım. O deneyimde, Astro’nun astro build komutunun belirli plugin’ler veya büyük projelerle birlikte aşırı bellek kullanabildiğini görmüştüm.

Bu seferki sorun, build süreciyle değil, çalışma zamanındaki (runtime) bir problemle ilgiliydi. Ancak her iki durumda da temel neden aynıydı: yetersiz bellek veya bellek sızıntısı. Kendi VPS’imde 13’ten fazla Docker container yönettiğim için, her servisin bellek kullanımını dikkatle izlemem gerekiyor. Bu tür OOM durumları, sadece o servisi değil, tüm sistemi etkileyebiliyor.

Bellek Sızıntısını Tespit Etmek

Node.js’te bellek sızıntısını tespit etmek genellikle zordur. Ancak, uygulamanın belirli bir işlevi tetiklediğinde belleğin sürekli arttığını ve asla geri düşmediğini gözlemledim. Bu, bir nesnenin referansının tutulduğu ve çöp toplayıcı tarafından serbest bırakılamadığı anlamına gelir. Kod tabanını incelediğimde, gelen verileri işleyen bir modülde, büyük veri setlerini işlerken oluşan geçici nesnelerin doğru şekilde temizlenmediğini fark ettim.

Özellikle, bir array’e sürekli olarak yeni veri ekleniyor ve bu array’in boyutu kontrol edilmiyordu. İşlem bittikten sonra bile bu array bellekte kalıyordu. Bu durum, zamanla bellek kullanımının artmasına ve sonunda OOM Killer’ın devreye girmesine neden oluyordu. Bu, benim için “kurumsal danışman” tonunda değil, bizzat yaşadığım, “olur o kadar” diyebileceğim türden bir hataydı.

Çözüm: Hafıza Sızıntısını Gidermek ve Önlemler Almak

Sorunun kök nedenini belirledikten sonra, çözümü uygulamak nispeten kolay oldu. Bellek sızıntısına neden olan kod bloğunu buldum ve gelen verileri işledikten sonra ilgili nesnelerin doğru şekilde null’a atanarak veya scope dışına çıkarılarak belleğin serbest bırakılmasını sağladım.

// Eski ve sorunlu kod örneği (basitleştirilmiş)
let largeDataArray = [];
function processData(newData) {
  largeDataArray.push(newData); // Sürekli veri ekleniyor ve array büyüyor
  // ... veri işleme ...
  // largeDataArray'in temizlenmesi veya sınırlandırılması yok
}

// Düzeltilmiş kod örneği
let largeDataArray = [];
const MAX_ARRAY_SIZE = 1000; // Maksimum boyut belirlendi

function processData(newData) {
  largeDataArray.push(newData);
  if (largeDataArray.length > MAX_ARRAY_SIZE) {
    largeDataArray.shift(); // En eski eleman çıkarılarak array sınırlandırıldı
  }
  // ... veri işleme ...
}

// Alternatif olarak, işlem bittikten sonra null'a atanabilir
function processDataAndClean(newData) {
  let processedItem = { ...newData, processed: true };
  // ... veri işleme ...
  processedItem = null; // İşlem sonrası nesne serbest bırakıldı
}

Bu değişikliği yaptıktan sonra, uygulamayı tekrar başlattım ve htop ile bellek kullanımını izlemeye devam ettim. Bu kez, bellek kullanımı stabil kaldı ve OOM Killer tetiklenmedi. Ancak bu sadece ilk adımdı. Bu tür olayların tekrar yaşanmaması için ek önlemler almam gerekiyordu.

Geleceğe Yönelik Önlemler

  1. Daha Fazla RAM: Mevcut VPS’imin RAM kapasitesini artırmayı düşündüm. Ancak bu, maliyeti de artıracak bir seçimdi. Mevcut kaynakları daha verimli kullanmak her zaman ilk tercihim olmuştur.
  2. Monitoring ve Alerting: Prometheus ve Grafana gibi araçlarla daha detaylı bir izleme sistemi kurdum. Bellek kullanımı belirli bir eşiği aştığında otomatik uyarılar alacak şekilde yapılandırdım. Bu sayede, OOM Killer devreye girmeden sorunu tespit edebileceğim.
  3. Resource Limits (Docker): Mümkün olduğunca her container için belirli bellek limitleri belirledim. Bu, bir container’ın tüm sistemi ele geçirmesini engeller. Örneğin, docker run --memory=512m ... gibi.
  4. Otomatik Yeniden Başlatma Mekanizmaları: systemd’nin Restart=on-failure ayarını daha agresif hale getirdim. Bu, uygulama çöktüğünde otomatik olarak yeniden başlatılmasını sağlar.
  5. Daha Sık Code Review: Özellikle bellek yönetimiyle ilgili kritik bölümlerin daha sık gözden geçirilmesi için bir süreç oluşturdum.

Bu kriz, bana kendi altyapımı yönetmenin hem büyük bir sorumluluk hem de sürekli bir öğrenme süreci olduğunu bir kez daha hatırlattı. Müşteri toplantısında yaşanan o panik anı, beni daha dikkatli ve daha hazırlıklı olmaya itti.

Bir sonraki yazıda, bu tür incident response süreçlerinde kullandığım “preflight resource guard + auto-fix + dedup-alert” pattern’ini daha detaylı anlatacağım.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Haftalık özet — AI değil, bizzat ben seçiyorum

Haftada bir mail: o haftanın en önemli yazısı, perde arkası notları, ve "bu hafta gerçekten kullandığım araç" bölümü. Az gürültü, çok sinyal.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar