avatar
·4 dk okuma
Node.js ve Thread Pool: Asenkron İşlemlerin Temelleri

Node.js ve Thread Pool: Asenkron İşlemlerin Temelleri

Node.js, JavaScript tabanlı sunucu tarafı uygulamalar geliştirmek için kullanılan popüler bir platformdur. Asenkron ve non-blocking yapısıyla öne çıkan Node.js, yüksek performanslı ve ölçeklenebilir uygulamalar geliştirilmesine olanak tanır. Bu makalede, Node.js'in bu özelliklerini mümkün kılan temel bileşenlerden biri olan thread pool (iş parçacığı havuzu) ve libuv kütüphanesi hakkında detaylı bilgi verilecektir.

Asenkron ve Non-blocking Yapının Temelleri

Node.js, tek iş parçacıklı bir çalışma modeline sahiptir. Bu, tüm JavaScript kodunun tek bir iş parçacığı üzerinde çalıştığı anlamına gelir. Peki, zaman alan işlemler sırasında ana iş parçacığının bloklanmasını nasıl engeller? İşte burada asenkron ve non-blocking (engellemesiz) yapı devreye girer.

Asenkron ve non-blocking yapı sayesinde, zaman alan işlemler ana iş parçacığını bloklamadan arka planda gerçekleştirilebilir. Örneğin, dosya okuma veya HTTP istekleri gibi işlemler asenkron olarak gerçekleştirilir. Bu sayede, ana iş parçacığı diğer işlemleri gerçekleştirmeye devam edebilir.

thread pool
FS Modülü ile Asenkron Dosya Okuma
const fs = require('fs');

console.log('Başlangıç');

fs.readFile('dosya.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

console.log('Bitiş');

Yukarıdaki kodda, fs.readFile metodu kullanılarak bir dosya asenkron olarak okunur. Kod çalıştırıldığında, Başlangıç ve Bitiş mesajları sırasıyla konsola yazdırılır. Dosya okuma işlemi tamamlandığında ise dosyanın içeriği konsola yazdırılır. Bu, asenkron yapının bir örneğidir: dosya okuma işlemi arka planda gerçekleştirilirken ana iş parçacığı çalışmaya devam eder.

Libuv ve Thread Pool

Node.js'in asenkron ve non-blocking yapısını sağlayan temel bileşenlerden biri libuv kütüphanesidir. Libuv, Node.js'in altında yatan düşük seviye kütüphanedir ve asenkron I/O işlemlerini yönetir. İş parçacığı havuzu, genellikle zaman alan dosya sistem erişimleri veya kriptografik işlemler gibi CPU yoğun görevler için kullanılır.

İş Parçacığı Havuzunun İşleyişi

Libuv, iş parçacığı havuzu (thread pool) kullanarak zaman alan görevleri ana iş parçacığından bağımsız olarak çalıştırır. İş parçacığı havuzu, varsayılan olarak dört iş parçacığı içerir, ancak ihtiyaçlara göre konfigüre edilebilir. Ana iş parçacığı, zaman alan bir görevle karşılaştığında, görevi libuv'ye devreder ve libuv, bu görevi iş parçacığı havuzundaki uygun bir iş parçacığına atar.

libuv

Örneğin, dosya okuma işlemi aşağıdaki gibi libuv tarafından iş parçacığı havuzuna atanabilir:

fs.readFile('dosya.txt', 'utf8', (err, data) => {
    if (err) throw err;
    console.log(data);
});

Bu işlem, libuv tarafından iş parçacığı havuzuna atanır ve bir iş parçacığı bu görevi tamamlar. Görev tamamlandığında, ilgili geri çağırım fonksiyonu (callback) çalıştırılır.

Kriptografi ve CPU Yoğun İşlemler

Node.js'in crypto modülü, güvenli kriptografik işlemler gerçekleştirmek için kullanılır. Özellikle crypto.pbkdf2 (Password-Based Key Derivation Function 2) metodu, şifrelerin güvenli bir şekilde hash edilmesini sağlar. Bu metod, oldukça CPU yoğun bir işlemdir ve bu nedenle iş parçacığı havuzunu kullanarak ana iş parçacığının bloklanmasını önler.

PBKDF2 Metodunun Kullanımı
const crypto = require('crypto');

const start = Date.now();

crypto.pbkdf2('password', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
    if (err) throw err;
    console.log(`Türetilmiş anahtar: ${derivedKey.toString('hex')}`);
    console.log(`Süre: ${Date.now() - start} ms`);
});

Yukarıdaki kodda, crypto.pbkdf2 metodu kullanılarak bir şifre hash edilir. Bu işlem CPU yoğun bir işlem olduğundan, libuv tarafından iş parçacığı havuzuna atanır ve ana iş parçacığı bloklanmadan diğer işlemleri gerçekleştirmeye devam edebilir.

thread pool

Performans Ölçümleri ve Karşılaştırmalar

Asenkron ve senkron metodlar arasındaki performans farkını anlamak için birkaç deney gerçekleştirelim.

Senkron Metodların Performansı

Senkron metodlar, ana iş parçacığını bloklayarak çalışır. Örneğin, crypto.pbkdf2Sync metodu senkron olarak çalışır ve ana iş parçacığını bloklar.

const start = Date.now();

const key = crypto.pbkdf2Sync('password', 'salt', 100000, 64, 'sha512');
console.log(`Türetilmiş anahtar: ${key.toString('hex')}`);
console.log(`Süre: ${Date.now() - start} ms`);

Bu kod çalıştırıldığında, pbkdf2Sync metodu tamamlanana kadar ana iş parçacığı bloklanır ve diğer işlemler gerçekleştirilmez.

Asenkron Metodların Performansı

Asenkron metodlar, iş parçacığı havuzunu kullanarak çalışır ve ana iş parçacığını bloklamaz. Yukarıda verilen crypto.pbkdf2 örneği, asenkron metodun nasıl çalıştığını göstermektedir.

Bu metod, iş parçacığı havuzunda bir iş parçacığı tarafından gerçekleştirilir ve ana iş parçacığı diğer işlemleri gerçekleştirmeye devam eder. Bu sayede, aynı anda birden fazla asenkron işlem gerçekleştirilerek paralel işlem yapılabilir.

Sonuç ve Özet

Node.js'in asenkron ve non-blocking yapısı, yüksek performanslı ve ölçeklenebilir uygulamalar geliştirilmesine olanak tanır. Bu yapının temel bileşenlerinden biri olan libuv ve iş parçacığı havuzu, zaman alan işlemleri ana iş parçacığından bağımsız olarak gerçekleştirir. Bu sayede, ana iş parçacığı bloklanmadan diğer işlemleri gerçekleştirebilir.

Node.js'in bu özellikleri, özellikle yüksek trafik alan web uygulamaları ve gerçek zamanlı uygulamalar geliştirmek için idealdir. İş parçacığı havuzunun verimli kullanımı ve asenkron metodların doğru şekilde uygulanması, performansın ve kullanıcı deneyiminin optimize edilmesine yardımcı olur.

Gelecekte daha karmaşık konulara geçmeden önce, bu temel bilgileri anlamak Node.js ile etkili ve verimli kod yazmanın ilk adımıdır. Bu bilgileri pekiştirmek ve daha ileri seviye konuları öğrenmek için pratik yapmak ve Node.js dokümantasyonuna başvurmak önemlidir.