Sunucu yönetimi, bana kalırsa, yazılımdan çok insan yönetimine benziyor. Yirmi yılın sonunda anladım ki en büyük hatalarımı teknik eksikliklerim değil, ‘evet’ deme alışkanlığım ve gözden kaçırdığım basit varsayımlar tetiklemiş. Bu süreçte karşılaştığım her sorun, beni bir adım daha ileri taşıyan, bazen pahalıya mal olan bir derse dönüştü.
Bu serüvende öğrendiğim 20 dersi, tek tek maddeler halinde sıralamak yerine, deneyimlerimden süzülen ana temalar altında anlatmak istedim. Çünkü işin özü, sadece teknik bilgi değil, aynı zamanda o bilginin arkasındaki düşünce yapısı ve problem çözme yaklaşımı. Gelin, bu derslere birlikte bakalım.
Varsayımların Tehlikesi ve Gözden Kaçan Detaylar
Sunucu dünyasında “sanırım çalışır” demek, “kesin bozulur” demenin kibar halidir. Kariyerimin ilk yıllarında, bir müşteri projesinde network segmentasyonu yaparken, VLAN tagging’in her noktada beklendiği gibi işleyeceğini varsaydım. Sonuç? Kritik bir sistem uzun süre erişilemez hale geldi, çünkü aradaki eski bir switch’in portunda default VLAN farklıydı. Bu basit gözden kaçırma, bana pahalıya patladı.
Bir keresinde, bir yan ürünümün backend’inde Redis’in bellek kullanımını doğru optimize ettiğimi düşünüyordum. Ancak OOM eviction policy seçimini yanlış yaptığım için, belirli bir yük altında Redis aniden duruyordu. journald loglarında sadece “OOM-killed” görmek, sorunun kaynağını bulmak için günlerce cgroup limitlerini ve Redis konfigürasyonunu incelememe neden oldu. Bu tür küçük detaylar, bir sistemin stabilitesini derinden etkileyebilir.
İnsan Faktörü ve Süreçlerin Gücü
Teknik mimariler ne kadar mükemmel olursa olsun, işin içinde insan ve iş süreçleri varsa, her şey değişir. Bir üretim ERP’sinde çalışırken fark ettim ki, yazılım mimarisi çoğu zaman teknik bir mimari değil, organizasyonel akıştır. Gecikmeli sevkiyat raporları hep eksik geliyordu; sebebi SQL sorgusu ya da performans problemi değil, sahadaki operatörlerin ekranları doğru zamanda güncellemeyi unutmasıydı. Bu, bana yazılımın sadece koddan ibaret olmadığını, kullanıcı deneyimi ve iş akışıyla bir bütün olduğunu gösterdi.
Bir başka derste, “evet” demenin bedelini çok ağır ödedim. Bir proje yöneticisi, “küçük bir özellik” için hızlı bir teslimat istediğinde, olası yan etkilerini ve test süresini hafife alıp “evet” dedim. Sonuç olarak, o “küçük özellik” uzun süren bir regresyon test döngüsüne ve sancılı bir rollback operasyonuna yol açtı. Bazen doğru cevap “hayır”dır, ya da “ancak bu koşullarla” demeyi öğrenmek gerekir.
Güvenlik Bir Süreçtir, Tek Seferlik Proje Değil
Sistem güvenliği, bir duvar örmek gibi değildir; sürekli tetikte olmayı gerektiren, yaşayan bir organizmadır. Bir bankanın iç platformunda CVE takibinin ne kadar kritik olduğunu gördüm. Kritik bir kernel zafiyeti (örneğin algif_aead gibi bir kripto modülünde) çıktığında, kısa sürede kernel module blacklist uygulamak zorunda kaldık. Bu, güvenlik güncellemelerinin sadece “bir ara yapılır” denemeyecek kadar hayati olduğunu öğretti.
fail2ban kurallarını yazarken bile, saldırganların ne kadar yaratıcı olabileceğini gördüm. Basit regex’ler yerine, JWT/OAuth2 paternlerini ve rate limiting mekanizmalarını doğru kurgulamak, SQL injection denemelerini veya DDoS katmanlarını bertaraf etmek için hayati. Güvenlik, sürekli öğrenmeyi ve güncel kalmayı gerektiren bir alandır; bir kez kurup unutabileceğiniz bir şey değil.
Operasyonel Borç ve Görünürlüğün Önemi
Operasyonel borç, teknik borç kadar tehlikelidir ve genellikle daha sinsi ilerler. PostgreSQL’de WAL bloat’ı izlemeyi atladığım bir dönemde, disklerimizin beklenenden çok daha hızlı dolduğunu gördüm. Ya da systemd unit’lerinin timer’larının reliability’sini gözden kaçırdığımda, kritik bir yedekleme işinin aylarca çalışmadığını ancak bir denetimde fark ettim. Eğer bir şeyi monitör etmiyorsanız, çalışıp çalışmadığını asla bilemezsiniz.
Observability sadece metrik, log ve trace toplamak değildir; aynı zamanda bu veriyi anlamlı hale getirmek ve aksiyon alınabilir alarmlar üretmektir. Bir keresinde, bir bare-metal sunucuda Docker Compose ile uygulamalarımı çalıştırırken, container memory limit’lerini doğru ayarlamadığım için build OOM hatalarıyla karşılaştım. journald’nin rate limit’lerini anlamak ve cgroup memory.high yumuşak limitlerini doğru kullanmak, bu tür sorunları önceden tespit etmemi sağladı.
Basitlik ve Sağlamlığın Değeri
Zamanla anladığım en önemli derslerden biri, basitliğin gücü. Monolith mi, microservice mi tartışmalarında, benim tercihim hep “ihtiyaç kadar karmaşıklık” oldu. Bir üretim firmasının ERP’sini geliştirirken, event-sourcing ve CQRS gibi pattern’leri düşündük, ama mevcut ekibin ve altyapının bunu kaldırıp kaldıramayacağını hesaplayarak, daha pragmatik, modüler bir monolith ile başladık. Bu, bize hem hızlı teslimat sağladı hem de operasyonel yükümüzü azalttı.
Sistem tasarlarken, idempotency ve transaction outbox gibi kavramları her zaman aklımda tutarım. Özellikle dağıtık sistemlerde eventual consistency ile çalışırken, bir operasyonun birden fazla kez çalışsa bile aynı sonucu vereceğinden emin olmak kritik. Bu basit ama güçlü prensipler, sistemlerimin uzun vadede daha sağlam ve yönetilebilir olmasını sağlıyor.
Sunucu yönetimi, sürekli öğrenme ve adaptasyon gerektiren bir yolculuk. Benim bu serüvende öğrendiğim en kıymetli derslerden bazıları bunlar. Sizin bu yolda öğrendiğiniz en kıymetli ders ne oldu? Benimkilerle örtüşüyor mu, yoksa bambaşka dersler mi çıkardınız? Yorumlarda merakla bekliyorum.