avatar
·4 dk okuma
Node.js Cluster Modülü: Performans ve Ölçeklenebilirlik için Güçlü Bir Araç

Node.js Cluster Modülü: Performans ve Ölçeklenebilirlik için Güçlü Bir Araç

Node.js, asenkron yapısı ve tek iş parçacıklı çalışma modeli sayesinde yüksek performanslı uygulamalar geliştirmek için ideal bir platformdur. Ancak, CPU yoğunluklu işlemler söz konusu olduğunda bu tek iş parçacıklı model bazı sınırlamalara sahiptir. Bu makalede, Node.js'in bu sınırlamaları aşmak için sunduğu cluster modülünü detaylı bir şekilde inceleyeceğiz.

Tek İş Parçacıklı Mimarinin Sınırlamaları

Node.js tek iş parçacıklı bir çalışma modeli kullanır. Bu, Node.js'in sadece bir CPU çekirdeğini kullanabileceği anlamına gelir. I/O operasyonları (dosya okuma/yazma, ağ istekleri gibi) için bu model son derece verimlidir çünkü bu tür işlemler genellikle CPU'yu meşgul etmez. Ancak, uzun süren ve CPU yoğunluklu işlemler (örneğin, büyük veri setlerinin işlenmesi, karmaşık hesaplamalar) söz konusu olduğunda performans sorunları ortaya çıkabilir. Tek bir iş parçacığı bu tür işlemlerle meşgul olduğunda, diğer istekler gecikebilir ve uygulamanın genel performansı düşebilir.

Cluster Modülünün Tanıtımı

Node.js, bu performans sorunlarını aşmak için cluster modülünü tanıtmıştır. Cluster modülü, aynı anda çalışan birden fazla child process (çalışanlar) oluşturmayı sağlar. Bu çalışanlar aynı uygulamanın birden fazla kopyasını çalıştırır ve gelen istekleri paylaşarak işlem yükünü dengeler. Her çalışan, kendi olay döngüsüne, belleğine ve V8 JavaScript motoru örneğine sahiptir.

Cluster Modülünün Temel Prensipleri
  1. Master ve Worker Süreçleri: Cluster modülü kullanıldığında, Node.js uygulaması bir master süreç olarak başlatılır. Bu master süreç, çalışan süreçleri oluşturur ve yönetir. Master süreç, çalışanların başlatılması, durdurulması ve yeniden başlatılması gibi görevlerden sorumludur ancak uygulama kodunu çalıştırmaz.

  2. İş Yükü Dağıtımı: Her çalışan süreç, uygulamanın bir kopyasını çalıştırır ve gelen istekleri işler. Bu sayede, iş yükü birden fazla çalışan süreç arasında dağıtılır ve performans iyileştirilir. Örneğin, bir çalışan uzun süren bir işlemi yürütürken diğer çalışanlar yeni gelen istekleri işleyebilir.

  3. Aynı Portu Paylaşma: Tüm çalışan süreçler aynı sunucu portunu paylaşır. Bu, master sürecin iş yükünü otomatik olarak çalışan süreçler arasında dağıtmasını sağlar.

Cluster Modülü ile Örnek Uygulama

Cluster modülünün nasıl çalıştığını daha iyi anlamak için basit bir örnek uygulama oluşturacağız. Bu uygulama, cluster modülünü kullanmadan önce ve kullandıktan sonra performans karşılaştırması yapacak.

Cluster Modülü Kullanmadan Basit HTTP Sunucusu

Öncelikle, cluster modülünü kullanmadan basit bir HTTP sunucusu oluşturalım:

const http = require('http');

const server = http.createServer((req, res) => {
    if (req.url === '/') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Home Page');
    } else if (req.url === '/slow-page') {
        // Uzun süren bir işlem simülasyonu
        for (let i = 0; i < 1e7; i++);
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Slow Page');
    }
});

server.listen(8000, () => {
    console.log('Server listening on port 8000');
});

Bu örnekte, / rotası hızlı bir yanıt verirken, /slow-page rotası uzun süren bir for döngüsü nedeniyle yavaş yanıt verir. Eğer /slow-page yüklenirken aynı anda / rotasına bir istek yaparsak, ikinci istek de yavaş yanıt verecektir çünkü tek iş parçacığı bu uzun süren işlemle meşgul olacaktır.

Cluster Modülü ile Geliştirilmiş HTTP Sunucusu

Şimdi aynı sunucuyu cluster modülü kullanarak geliştirelim:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    console.log(`Master ${process.pid} is running`);

    // Çekirdek sayısı kadar işçi süreç oluşturma
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} died`);
    });
} else {
    // İşçi süreçlerin çalıştırdığı kod
    const server = http.createServer((req, res) => {
        if (req.url === '/') {
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('Home Page');
        } else if (req.url === '/slow-page') {
            for (let i = 0; i < 1e7; i++);
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('Slow Page');
        }
    });

    server.listen(8000, () => {
        console.log(`Worker ${process.pid} started`);
    });
}

Bu kodda, master süreç CPU çekirdek sayısı kadar işçi süreç oluşturur. Her işçi süreç, gelen istekleri işleyerek performansı iyileştirir. Aynı anda hem / rotasına hem de /slow-page rotasına yapılan isteklerin her biri farklı işçiler tarafından işlendiği için birbirini bloke etmez.

Optimum İşçi Sayısını Belirleme

İşçi süreçlerin sayısını belirlerken, sistemdeki CPU çekirdek sayısı dikkate alınmalıdır. Çok fazla işçi oluşturmak, sistemde aşırı yüklenmeye ve performans düşüşüne yol açabilir. os modülünü kullanarak sistemdeki CPU çekirdek sayısını öğrenebiliriz:

const os = require('os');
console.log(os.cpus().length);

Bu kod, sistemdeki CPU çekirdek sayısını konsola yazdıracaktır. Örneğin, 8 çekirdekli bir sistemde bu değer 8 olacaktır.

pm2 ile Cluster Yönetimi

Cluster modülünü manuel olarak yönetmek yerine, pm2 gibi bir süreç yöneticisi kullanarak işleri kolaylaştırabiliriz. pm2, uygulamanızı cluster modunda çalıştırmanızı ve optimum işçi sayısını otomatik olarak belirlemenizi sağlar.

pm2'yi global olarak yüklemek için şu komutu kullanabilirsiniz:

sudo npm install -g pm2

Ardından, uygulamanızı pm2 ile cluster modunda çalıştırabilirsiniz:

pm2 start cluster.js -i 0

Buradaki -i 0 parametresi, pm2'nin en uygun işçi sayısını otomatik olarak belirlemesini sağlar. pm2 ayrıca süreçleri izleme, yeniden başlatma ve durdurma gibi işlevler de sunar.

Sonuç

Node.js'in cluster modülü, tek iş parçacıklı modelin sınırlamalarını aşmak için güçlü bir araçtır. Uzun süren ve CPU yoğunluklu işlemler sırasında uygulamanızın performansını iyileştirir. Cluster modülü ile uygulamanızın iş yükünü birden fazla süreç arasında dağıtarak daha ölçeklenebilir ve yüksek performanslı uygulamalar geliştirebilirsiniz. Ayrıca, pm2 gibi araçlar kullanarak süreç yönetimini otomatikleştirip daha da kolaylaştırabilirsiniz. Node.js ile büyük ve karmaşık uygulamalar geliştirirken cluster modülünün sunduğu avantajlardan faydalanmanız, performans ve kullanıcı deneyimini artırmanıza yardımcı olacaktır.