Node.js İle Cluster Modülü Kullanarak Çok Çekirdekli İşlemci Yönetimi Nasıl Yapılır?

Node.js İle Cluster Modülü Kullanarak Çok Çekirdekli İşlemci Yönetimi Nasıl Yapılır?
Node.js İle Cluster Modülü Kullanarak Çok Çekirdekli İşlemci Yönetimi Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Uygulamaya başlamadan önce sisteminizde Node.js'in güncel bir LTS (Long Term Support) sürümünün yüklü olması gerekmektedir. 2026 yılı itibarıyla Node.js 22 veya üzeri sürümler, cluster modülü ile en kararlı ve performanslı çalışmayı sunmaktadır.

  • Node.js (v22.x veya üzeri)
  • Temel JavaScript (ES6+ modül sistemi) bilgisi
  • İşletim sistemi: Linux, macOS veya Windows
  • Terminal veya komut satırı arayüzü kullanım yetkinliği

Kurulumu doğrulamak için terminalinize node -v komutunu yazarak sürümünüzü kontrol edebilirsiniz. Geliştirme ortamınızda herhangi bir ek paket yüklemenize gerek yoktur; cluster modülü Node.js çekirdeği ile birlikte yerleşik (built-in) olarak gelmektedir.

Cluster Modülü Nedir ve Neden Kullanılır?

Cluster modülü, ana bir "master" (yönetici) sürecin, uygulamanızın kopyalarını "worker" (işçi) süreçler olarak oluşturmasına olanak tanır. Her bir worker süreci kendi olay döngüsüne ve bellek alanına sahiptir. Bu sayede, tek bir CPU çekirdeğinin darboğaz oluşturması engellenir ve gelen istekler işletim sistemi seviyesinde tüm çekirdeklere dağıtılır.

Aşağıdaki tablo, cluster modülünün geleneksel tek süreçli yapı ile karşılaştırmasını sunmaktadır:

Özellik Tek Süreç (Single Process) Cluster Modülü
CPU Kullanımı Sadece 1 çekirdek Tüm kullanılabilir çekirdekler
Hata Toleransı Süreç ölürse uygulama durur Worker ölürse diğeri devam eder
Karmaşıklık Düşük Orta (IPC yönetimi gerekir)

Adım Adım Cluster Yapılandırması

İlk adımda, sistemdeki CPU çekirdek sayısını tespit edip, her çekirdek için bir worker süreci başlatacağız. Bu işlem, uygulamanın donanım kapasitesini tam olarak kullanmasını sağlar.

const cluster = require('cluster');
const http = require('http');
const os = require('os');

const numCPUs = os.cpus().length;

if (cluster.isPrimary) {
  console.log(`Master süreç ${process.pid} başlatıldı.`);

  // Her CPU için worker oluştur
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} kapandı.`);
  });
} else {
  // Worker süreçleri burada HTTP sunucusunu başlatır
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Merhaba, çok çekirdekli dünyadan!\n');
  }).listen(8000);
}

Bu kod bloğunda, cluster.isPrimary kontrolü ile ana sürecin worker'ları oluşturmasını sağlıyoruz. Worker süreçler ise aynı portu (8000) dinlemelerine rağmen, işletim sistemi gelen istekleri bu süreçler arasında otomatik olarak paylaştırır.

Worker Süreçlerin Yönetimi ve Hata Toleransı

Üretim ortamında bir worker sürecinin çökmesi, uygulamanın tamamının durmasına neden olmamalıdır. Cluster modülü, ölen bir süreci otomatik olarak yeniden başlatmamıza olanak tanır. Bu, uygulamanızın sürekli ayakta kalmasını sağlayan "Self-Healing" (kendi kendini iyileştirme) mekanizmasıdır.

if (cluster.isPrimary) {
  // Worker'ları başlat
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // Ölen worker'ı izle ve yerine yenisini aç
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} çöktü. Yenisi başlatılıyor...`);
    cluster.fork();
  });
}

Bu yaklaşım, uygulamanızın beklenmedik hatalar (uncaught exceptions) karşısında dirençli olmasını sağlar. Ancak, bir worker'ın sürekli çökmesi durumunda bir döngüye girmemek için "restart limit" mekanizması eklemek iyi bir pratik olacaktır.

İletişim: Master ve Worker Arasında Mesajlaşma

Worker süreçler bağımsız oldukları için bellekleri paylaşmazlar. Eğer süreçler arasında veri paylaşmanız gerekirse, process.send() ve process.on('message') yöntemlerini kullanarak süreçler arası iletişim (IPC) kurmalısınız.

// Worker içinde mesaj gönderme
process.send({ cmd: 'notify', msg: 'İşlem tamamlandı' });

// Master içinde mesajı dinleme
cluster.on('message', (worker, message) => {
  if (message.cmd === 'notify') {
    console.log(`Worker ${worker.id} mesaj gönderdi: ${message.msg}`);
  }
});

Bu yöntem, özellikle merkezi bir loglama sistemi veya iş dağıtım mekanizması kurarken oldukça hayatidir. Ancak, IPC üzerinden çok büyük veri paketleri göndermek performansı düşürebilir; bu nedenle veri transferini minimumda tutmalısınız.

Üretim Ortamı İçin Kritik Güvenlik ve Performans Uyarıları

Kritik Uyarı: Cluster modülü tek başına bir yük dengeleyici (Load Balancer) değildir. Çok yüksek trafikli uygulamalarda Nginx veya HAProxy gibi bir ters vekil sunucu (reverse proxy) kullanmak, güvenliği artırır ve SSL/TLS sonlandırmasını daha verimli yönetmenizi sağlar. Ayrıca, worker süreçler arasında paylaşılan bir durum (state) tutmanız gerekiyorsa, Redis gibi harici bir önbellek katmanı kullanmalısınız; çünkü worker'lar arası bellek paylaşımı mümkün değildir.

Güvenlik tarafında, worker süreçlerinizin yetkilerini kısıtlamayı unutmayın. Her worker'ın sadece ihtiyaç duyduğu dosya sistemine erişimi olmalıdır. Ayrıca, SQL Injection ve XSS saldırılarına karşı giriş verilerini her zaman doğrulayın ve sanitize edin.

// Güvenli veri girişi örneği (Özet)
const sanitizeInput = (input) => {
  return input.replace(//g, ">");
};
// Veritabanı sorgularında her zaman parametreli sorgular (prepared statements) kullanın.

Sıkça Sorulan Sorular

Cluster modülü her uygulamada kullanılmalı mı?

Eğer uygulamanız I/O (Girdi/Çıktı) ağırlıklı ise ve CPU kullanımı düşükse, Node.js'in tek süreçli yapısı zaten yeterlidir. Ancak CPU yoğun işlemler (görüntü işleme, karmaşık matematiksel hesaplamalar) yapıyorsanız cluster kullanımı zorunludur.

PM2 gibi araçlar varken neden cluster modülünü manuel kullanayım?

PM2 gibi süreç yöneticileri, arka planda zaten cluster modülünü kullanır. Ancak, cluster modülünün nasıl çalıştığını anlamak, hata ayıklama (debugging) ve özel süreç yönetimi senaryolarında size tam kontrol sağlar.

Worker süreçler arasında bellek paylaşımı nasıl yapılır?

Worker süreçler bellek paylaşamaz. Paylaşılan bir veriye ihtiyacınız varsa Redis veya Memcached gibi bir "in-memory" veri tabanı kullanmanız gerekir.

Cluster modülü ile kaç worker oluşturmalıyım?

Genel kural, CPU çekirdek sayısı kadar worker oluşturmaktır. Daha fazlası, "context switching" (bağlam değiştirme) maliyeti nedeniyle performansı düşürebilir.

Worker süreçler aynı portu nasıl dinleyebiliyor?

Node.js, işletim sisteminin soket paylaşım mekanizmasını kullanır. Master süreç portu dinler ve gelen bağlantıları worker'lara dağıtır.

Cluster Modülünde Performans Analizi ve İzleme Stratejileri

Cluster modülü ile çok çekirdekli yapıya geçiş yapmak, uygulamanın teorik kapasitesini artırsa da, bu yapının performansını izlemek ve darboğazları tespit etmek kritik bir süreçtir. Worker süreçlerin CPU ve bellek tüketimini izlemek için standart process.memoryUsage() verilerinin ötesine geçmeniz gerekir.

Performans takibi için her worker sürecinin kendi metriklerini bir merkezi log sistemine veya Prometheus gibi bir zaman serisi veritabanına göndermesi önerilir. Aşağıdaki örnek, bir worker sürecinin kendi sağlık durumunu ve bellek kullanımını nasıl raporlayabileceğini göstermektedir:

const cluster = require('cluster');

if (cluster.isWorker) {
  setInterval(() => {
    const usage = process.memoryUsage();
    process.send({
      type: 'metrics',
      workerId: cluster.worker.id,
      rss: (usage.rss / 1024 / 1024).toFixed(2) + ' MB',
      heapUsed: (usage.heapUsed / 1024 / 1024).toFixed(2) + ' MB'
    });
  }, 5000);
}

Bu metrikleri toplarken dikkat etmeniz gereken temel noktalar şunlardır:

  • Event Loop Gecikmesi: Worker süreçlerin event loop'unun ne kadar süre bloke kaldığını ölçmek, uygulamanın yanıt süresini doğrudan etkileyen en önemli göstergedir.
  • Süreç Yeniden Başlatma Sıklığı: Eğer worker süreçleriniz çok sık yeniden başlatılıyorsa, bu durum bellek sızıntısı (memory leak) veya işlenemeyen istisnaların bir göstergesi olabilir.
  • İstek Dağılımı: Master sürecin istekleri worker'lara dağıtırken kullandığı algoritmanın (Round Robin) yükü eşit dağıtıp dağıtmadığını gözlemleyin.

Cluster Modülü ile İleri Hata Ayıklama (Debugging) Teknikleri

Çoklu süreç yapısında hata ayıklamak, tek süreçli uygulamalara göre daha karmaşıktır. Hata bir worker süreçte oluştuğunda, bu hatanın hangi süreçten kaynaklandığını anlamak için süreç kimliklerini (PID) loglara mutlaka dahil etmelisiniz. Node.js'in dahili hata ayıklayıcısını kullanırken, her worker için farklı bir debug portu açmanız gerekebilir.

Aşağıdaki yapı, hata ayıklama sırasında worker süreçlerin port çakışması yaşamadan izlenmesini sağlar:

const cluster = require('cluster');
const v8 = require('v8');

if (cluster.isMaster) {
  cluster.settings.inspectPort = 9229; // Master için temel port
  cluster.fork();
} else {
  // Worker süreçlerde hata ayıklama portunu dinamik atama
  const debugPort = 9230 + cluster.worker.id;
  process.debugPort = debugPort;
  console.log(`Worker ${cluster.worker.id} şu portta dinleniyor: ${debugPort}`);
}
İpucu: Üretim ortamında hata ayıklama portlarını asla dış dünyaya açmayın. Bu portlar üzerinden uygulamanızın kaynak koduna ve bellek yapısına erişim sağlanabilir.

Ayrıca, uncaughtException durumlarında süreci hemen öldürmek yerine, uygulamanın mevcut istekleri tamamlamasına izin veren "Graceful Shutdown" mekanizmasını mutlaka uygulayın. Bu, hata ayıklama sürecinde verilerin tutarlı kalmasını sağlar.

Sonuç

Node.js ile cluster modülü kullanarak çok çekirdekli işlemci yönetimi yapmak, uygulamanızın ölçeklenebilirliğini bir üst seviyeye taşır. Bu rehberde, süreç yönetimi, hata toleransı ve süreçler arası iletişim konularını temel düzeyden üretim standartlarına kadar inceledik. Bir sonraki adım olarak, uygulamanızı Docker konteynerleri içerisinde cluster modülü ile nasıl yapılandıracağınızı ve Kubernetes gibi orkestrasyon araçları ile nasıl entegre edeceğinizi araştırmanızı öneririm.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce güvenlik açıklarını (SQLi, XSS, DoS) göz önünde bulundurarak gerekli doğrulama katmanlarını eklediğinizden emin olun. Yazılım güvenliği sorumluluğu geliştiriciye aittir.

Bu yazıya tepkinizi paylaşın:
Mert Demir

Teknik konuları sadeleştirerek geniş kitlelere ulaştırma konusunda tutkuluyum. Ev işleri, bakım ve organizasyon temalı rehberlerimde kaliteyi ön planda tutuyorum.

Yorumlar (0)

Yorum Yaz