Node.js, JavaScript'in asenkron programlama yeteneklerini kullanarak yüksek performanslı ve ölçeklenebilir uygulamalar geliştirmek için popüler bir platformdur. Bu makalede, Node.js'in çekirdeğinde yer alan üç önemli bileşeni ve bunların birbirleriyle nasıl etkileşimde bulunduklarını inceleyeceğiz: Event Loop, Thread Pool ve İşletim Sistemi. Bu bileşenler birlikte çalışarak asenkron işlemleri koordine eder ve uygulamaların verimli bir şekilde çalışmasını sağlar.
Sağ tarafta libuv bulunur. Asenkron bir metod çalıştırdığınızda, bu işlem libuv'a devredilir. libuv, görevi işletim sisteminin yerel asenkron mekanizmalarını kullanarak veya mümkün değilse iş parçacığı havuzunu kullanarak çalıştırır. Böylece ana iş parçacığı engellenmez.
Event Loop, Node.js’in kalbinde yer alır ve senkron ve asenkron kodların düzgün bir şekilde çalışmasını sağlayan merkezi bir mekanizmadır. JavaScript'in tek iş parçacıklı yapısı nedeniyle, Event Loop, bu tek iş parçacığı üzerinde asenkron işlemleri koordine ederek verimli bir şekilde çalıştırır.
Koordinasyon: Event loop, senkron ve asenkron görevlerin ne zaman ve nasıl yürütüleceğini koordine eder.
Callback Yürütme: Kuyruklarda bekleyen callback fonksiyonlarını yürütür.
Görev Planlama: Asenkron görevlerin çalışma sırasını belirler ve uygun kuyruklara yerleştirir.
Event Loop, Node.js uygulamanız çalıştığı sürece sürekli dönen bir döngüdür. Bu döngü, çeşitli kuyruklarda (queues) bulunan görevleri (tasks) belirli bir sırayla işler. Her döngüde, Event Loop şu adımları takip eder:
Microtask Queue: process.nextTick
ve Promise
callback'leri işlenir.
Timer Queue: Zamanlayıcı (setTimeout, setInterval) callback'leri yürütülür.
Microtask Queue: Timer görevlerinden sonra tekrar kontrol edilir.
IO Queue: Asenkron I/O operasyonlarının callback'leri yürütülür.
Microtask Queue: I/O görevlerinden sonra tekrar kontrol edilir.
Check Queue: setImmediate
fonksiyonunun callback'leri yürütülür.
Microtask Queue: Check görevlerinden sonra tekrar kontrol edilir.
Close Queue: Asenkron görevlerin kapanış olaylarına bağlı callback'ler yürütülür.
Microtask Queue: Döngü sonunda tekrar kontrol edilir.
Bu adımlar, her event loop döngüsünde tekrarlanır. Yeni görevler eklendikçe, event loop bu görevleri uygun kuyruklara ekler ve sırasıyla işler.
Thread Pool, Node.js'in asenkron işleme yeteneklerini genişleten bir bileşendir. Özellikle CPU yoğunluklu ve uzun süreli işlemleri yönetmek için kullanılır.
Ağır İşlemler: CPU yoğunluklu işlemler (örneğin, dosya okuma/yazma, kriptografik işlemler) thread pool tarafından yürütülür.
Bloklama İşlemleri: Uzun süren işlemler, ana iş parçacığını (event loop’u) engellememek için thread pool’da gerçekleştirilir.
Event loop, ağır veya uzun süreli bir işlemi thread pool’a devrettiğinde, bu işlem bir iş parçacığında (thread) yürütülür. İşlem tamamlandığında, sonuç event loop’a iletilir ve ilgili callback fonksiyonu çalıştırılır. Bu sayede, ana iş parçacığı bloke edilmeden diğer görevler yürütülmeye devam eder.
İşletim Sistemi, düşük seviyeli I/O işlemleri ve yerel asenkron mekanizmalarla doğrudan etkileşimde bulunur. İşletim sistemi, ağ istekleri, dosya sistemi erişimi gibi işlemleri yönetir.
Yerel Asenkron Mekanizmalar: Ağ istekleri gibi düşük seviyeli I/O işlemlerini yönetir.
Sistem Kaynak Yönetimi: Dosya sistemine erişim, ağ bağlantıları gibi kaynakları yönetir.
İşletim sistemi, mümkün olduğunda I/O işlemlerini yerel asenkron mekanizmaları kullanarak gerçekleştirir. Bu işlemler tamamlandığında, sonuçlar libuv aracılığıyla event loop’a iletilir ve ilgili callback fonksiyonları çalıştırılır.
Bu üç bileşen (Event Loop, Thread Pool ve İşletim Sistemi) birlikte çalışarak Node.js'in yüksek performanslı ve ölçeklenebilir bir platform olmasını sağlar.
Asenkron I/O İşlemleri:
Başlatma: Event loop, bir I/O işlemi başlattığında (örneğin, dosya okuma), bu görev libuv tarafından işletim sistemine veya thread pool’a devredilir.
Yürütme: İşletim sistemi, ağ istekleri gibi düşük seviyeli I/O işlemlerini yönetir. Thread pool, CPU yoğunluklu işlemleri yürütür.
Sonuçların Bildirilmesi: İşletim sistemi veya thread pool, tamamlanan işlemlerin sonuçlarını event loop’a bildirir.
İşleme: Event loop, sonuçları alır ve ilgili callback fonksiyonlarını yürütür.
CPU Yoğunluklu İşlemler:
Başlatma: Event loop, CPU yoğunluklu bir işlemi thread pool’a devreder.
Yürütme: Thread pool, bu işlemi bir iş parçacığında yürütür.
Sonuçların Bildirilmesi: İşlem tamamlandığında, sonuç event loop’a iletilir.
İşleme: Event loop, sonuçları alır ve ilgili callback fonksiyonlarını yürütür.
Zamanlayıcılar ve Diğer Asenkron Görevler:
Başlatma: Zamanlayıcılar (örneğin, setTimeout
) event loop tarafından zamanlayıcı kuyruğuna eklenir.
Yürütme ve İşleme: Belirtilen süre dolduğunda, event loop ilgili callback fonksiyonlarını yürütür.
Node.js'teki Event Loop, Thread Pool ve İşletim Sistemi, asenkron işlemlerin koordinasyonunu sağlayarak yüksek performanslı ve ölçeklenebilir uygulamalar geliştirmeyi mümkün kılar. Event Loop, senkron ve asenkron kodların yürütülmesini koordine ederken, Thread Pool ağır ve uzun süreli işlemleri üstlenir. İşletim Sistemi ise düşük seviyeli I/O işlemlerini yönetir. Bu bileşenlerin etkili bir şekilde birlikte çalışması, Node.js'in gücünü ve esnekliğini ortaya koyar. Bu yapı, geliştiricilere daha verimli ve etkili kod yazma imkanı sunar ve Node.js'in popülerliğini artırır.