Jak Node.js obsługuje tysiące żądań
Mówi się, że Node.js jest jednowątkowy.
Mimo to obsługuje tysiące żądań, odczytuje pliki i wykonuje wywołania API bez zatrzymywania się.
Jak to działa?
Odpowiedzią jest libuv.
libuv to biblioteka w języku C. Nadaje ona Node.js możliwości asynchronicznego i nieblokującego wejścia/wyjścia (I/O). JavaScript nie potrafi samodzielnie odczytywać plików ani zarządzać gniazdami sieciowymi. Node.js wykorzystuje libuv, aby komunikować się z systemem operacyjnym.
Bez libuv JavaScript zatrzymałby się za każdym razem, gdy odczytywałbyś plik. Twoja aplikacja przestałaby odpowiadać.
Dzięki libuv odczyt pliku odbywa się w tle. JavaScript kontynuuje wykonywanie pozostałego kodu.
Przykład:
console.log("Start");
fs.readFile("data.txt", "utf8", (err, data) => {
console.log(data);
});
console.log("End");
Wynik: Start End (zawartość pliku)
Node.js wypisuje "End" przed zakończeniem odczytu pliku. Nie czeka.
Jak libuv zarządza Twoim kodem:
• Pętla zdarzeń (Event Loop): libuv uruchamia pętlę, która sprawdza, czy zadania zostały zakończone. Gdy zadania dobiegają końca, libuv umieszcza funkcje zwrotne (callbacks) w kolejce. • Pula wątków (Thread Pool): JavaScript korzysta z jednego wątku. libuv korzysta z puli wątków roboczych. Domyślnie pula ta posiada 4 wątki. Wątki te obsługują ciężkie zadania, takie jak:
- Operacje na systemie plików
- Zapytania DNS
- Kompresja
- Kryptografia • Networking: libuv zarządza gniazdami HTTP, TCP i UDP. Pozwala to serwerom obsługiwać wiele połączeń jednocześnie. • Timery: libuv obsługuje setTimeout i setInterval.
Przepływ wykonania wygląda następująco:
- JavaScript uruchamia Twój kod.
- libuv przenosi ciężkie zadania do tła.
- JavaScript przechodzi do następnej linii.
- libuv powiadamia pętlę zdarzeń (Event Loop), gdy zadanie zostanie zakończone.
- Pętla zdarzeń uruchamia Twoją funkcję zwrotną (callback).
Wyobraź sobie pizzerię.
Bez libuv stoisz przy ladzie i co dziesięć sekund pytasz: „Czy moje jedzenie jest gotowe?”. Blokujesz kolejkę.
Dzięki libuv składasz zamówienie, siadasz i czekasz na powiadomienie. Możesz robić inne rzeczy, dopóki pizza nie będzie gotowa.
Podsumowanie:
• Wykonywanie JavaScript: V8 Engine • Pętla zdarzeń (Event Loop): libuv • Operacje wejścia/wyjścia plików (File I/O): libuv • Sieć: libuv • Timery: libuv
libuv to silnik, który sprawia, że Node.js jest szybki.
