Gereksinimler ve Ön Hazırlık
Worker Threads modülü ile çalışabilmek için sisteminizde Node.js'in güncel bir sürümünün (v16.0.0 ve üzeri önerilir) kurulu olması gerekir. Bu modül, Node.js çekirdeği ile birlikte geldiği için herhangi bir harici paket yüklemenize gerek yoktur.
- Node.js (LTS sürümü önerilir).
- Temel JavaScript (ES6+ sözdizimi) bilgisi.
- İşletim sistemi seviyesinde çoklu çekirdek desteği (modern tüm işlemciler destekler).
Projenizi başlatmak için bir klasör oluşturun ve terminalinizde npm init -y komutunu çalıştırarak bir package.json dosyası oluşturun. Kod örneklerimizi test etmek için main.js ve worker.js adında iki dosya oluşturacağız.
Worker Threads Temel Mantığı
Worker Threads, ana iş parçacığından bağımsız olarak çalışan küçük iş parçacıklarıdır. Her iş parçacığı kendi V8 izole ortamına ve kendi bellek alanına sahiptir. Ana iş parçacığı ile iş parçacıkları arasında veri alışverişi, mesajlaşma (message channel) yöntemiyle yapılır.
Aşağıdaki örnekte, ana dosyadan bir iş parçacığı oluşturmayı ve ona veri göndermeyi göreceğiz:
// main.js
const { Worker } = require('worker_threads');
function runWorker(data) {
const worker = new Worker('./worker.js', { workerData: data });
worker.on('message', (result) => console.log('Sonuç:', result));
worker.on('error', (err) => console.error(err));
}
runWorker({ sayi: 20 });
Bu kodda Worker sınıfını kullanarak worker.js dosyasını başlattık ve workerData ile ona veri gönderdik. İş parçacığı tamamlandığında message olayı tetiklenir.
İş Parçacığı İçinde Veri İşleme
Şimdi iş parçacığının (worker) gelen veriyi nasıl alıp işlediğine bakalım. worker_threads modülünden gelen workerData ve parentPort, veri alışverişi için temel araçlardır.
// worker.js
const { parentPort, workerData } = require('worker_threads');
// Karmaşık bir hesaplama simülasyonu
function fibonacci(n) {
if (n
Performans Optimizasyonu ve İş Parçacığı Havuzu (Worker Pool)
Her işlem için yeni bir Worker örneği oluşturmak, işletim sistemi üzerinde ciddi bir bellek ve CPU yükü oluşturur. Node.js uygulamalarında yüksek performans elde etmek için "Worker Pool" (İş Parçacığı Havuzu) mimarisini kullanmak en iyi pratiktir. Bu yöntem, önceden oluşturulmuş bir iş parçacığı grubunu hazır tutarak, gelen görevleri bu hazır işçilere dağıtır.
Aşağıdaki örnek, basit bir havuz mantığı ile görevlerin nasıl yönetileceğini göstermektedir:
// worker-pool.js
const { Worker } = require('worker_threads');
const os = require('os');
class WorkerPool {
constructor(workerPath, numThreads = os.cpus().length) {
this.workerPath = workerPath;
this.numThreads = numThreads;
this.workers = [];
this.queue = [];
for (let i = 0; i < numThreads; i++) {
this.workers.push(this.createWorker());
}
}
createWorker() {
const worker = new Worker(this.workerPath);
worker.on('message', (result) => {
worker.busy = false;
if (this.queue.length > 0) {
const { data, resolve } = this.queue.shift();
this.runTask(data).then(resolve);
}
});
worker.busy = false;
return worker;
}
runTask(data) {
return new Promise((resolve) => {
const worker = this.workers.find(w => !w.busy);
if (worker) {
worker.busy = true;
worker.postMessage(data);
worker.once('message', resolve);
} else {
this.queue.push({ data, resolve });
}
});
}
}
İleri Seviye Hata Ayıklama ve İzleme
Çoklu iş parçacıklı yapılarda hata ayıklama (debugging), ana iş parçacığından farklı bir süreç gerektirir. Hataların izini sürmek için worker.on('error') dinleyicisinin yanı sıra, iş parçacığının yaşam döngüsünü takip etmek için exit olayını kullanmalısınız.
Hata İzleme Stratejileri
- Exit Kodları: İş parçacığı beklenmedik şekilde sonlanırsa,
exit olayı 0'dan farklı bir kod döndürür. Bu kodları loglayarak sistemin neden çöktüğünü anlayabilirsiniz.
- Async Stack Traces: Node.js v12 ve üzerinde,
worker_threads ile gelen hatalar genellikle ana iş parçacığına taşınır. Ancak, karmaşık işlemlerde process.on('uncaughtException') ile worker içindeki hataları yakalamak önemlidir.
// Hata yakalama örneği
worker.on('exit', (code) => {
if (code !== 0) {
console.error(`Worker durduruldu, çıkış kodu: ${code}`);
}
});
worker.on('error', (err) => {
console.error('İş parçacığında kritik hata:', err.message);
});
Bu yapıları kullanarak, uygulamanızın ölçeklenebilirliğini artırabilir ve CPU yoğunluklu görevlerin ana döngüyü (Event Loop) bloke etmesini tamamen engelleyebilirsiniz. Özellikle veritabanı sorguları, büyük veri setlerinin işlenmesi veya görüntü işleme gibi görevlerde bu yöntemler standart hale getirilmelidir.


Yorumlar (0)
Yorum Yaz