[ Ten post jest aktualny na dzień 2012-09-02 (nowszy niż powyżej). ]
Node.js absolutnie skaluje się na maszynach wielordzeniowych.
Tak, Node.js to jeden wątek na proces. Jest to bardzo celowa decyzja projektowa i eliminuje potrzebę radzenia sobie z semantyką blokowania. Jeśli się z tym nie zgadzasz, prawdopodobnie jeszcze nie zdajesz sobie sprawy z tego, jak niesamowicie trudno jest debugować wielowątkowy kod. Aby uzyskać głębsze wyjaśnienie modelu procesu Node.js i dlaczego działa on w ten sposób (i dlaczego NIGDY nie będzie obsługiwać wielu wątków), przeczytaj mój drugi post .
Jak więc skorzystać z mojego 16-rdzeniowego urządzenia?
Dwie drogi:
- W przypadku dużych zadań obliczeniowych, takich jak kodowanie obrazu, Node.js może odpalać procesy potomne lub wysyłać wiadomości do dodatkowych procesów roboczych. W tym projekcie miałbyś jeden wątek zarządzający przepływem zdarzeń i procesami N wykonującymi ciężkie zadania obliczeniowe i przełamującymi pozostałe 15 procesorów.
- Aby skalować przepustowość w usłudze sieciowej, powinieneś uruchomić wiele serwerów Node.js w jednym urządzeniu, po jednym na rdzeń i rozdzielić ruch między nimi. Zapewnia to doskonałe powinowactwo procesora i skaluje przepustowość prawie liniowo wraz z liczbą rdzeni.
Skalowanie przepustowości w serwisie internetowym
Od wersji 6.0.X Node.js dołączono moduł klastra od razu po wyjęciu z pudełka, co ułatwia skonfigurowanie wielu pracowników węzłów, którzy mogą nasłuchiwać na jednym porcie. Zauważ, że NIE jest to to samo, co starszy moduł „klastra” learnboost dostępny przez npm .
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
Pracownicy będą rywalizować o akceptację nowych połączeń, a najmniej obciążony proces najprawdopodobniej wygra. Działa całkiem dobrze i może dość dobrze skalować przepustowość w urządzeniach wielordzeniowych.
Jeśli masz wystarczająco dużo obciążenia, aby zająć się wieloma rdzeniami, będziesz chciał zrobić jeszcze kilka rzeczy:
Uruchom usługę Node.js za web-proxy, takim jak Nginx lub Apache - coś, co może dławić połączenie (chyba że chcesz, aby warunki przeciążenia całkowicie obniżyły pole), przepisz adresy URL, podaj zawartość statyczną i proxy inne pod-usługi.
Okresowo przetwarzaj procesy robocze. W przypadku długotrwałego procesu nawet niewielki wyciek pamięci ostatecznie się zsumuje.
Skonfiguruj zbieranie / monitorowanie dziennika
PS: Dyskusja między Aaronem i Christopherem w komentarzach do innego postu (na początku tego pisma, jest to najwyższy post). Kilka komentarzy na ten temat:
- Model wspólnego gniazda jest bardzo wygodny, ponieważ pozwala wielu procesom nasłuchiwać na jednym porcie i konkurować o akceptację nowych połączeń. Koncepcyjnie możesz pomyśleć o gotowym Apache, który robi to ze znaczącym zastrzeżeniem, że każdy proces zaakceptuje tylko jedno połączenie, a następnie umrze. Utrata wydajności Apache polega na tworzeniu nowych procesów i nie ma nic wspólnego z operacjami gniazd.
- Dla Node.js, gdy N pracowników konkuruje na jednym gnieździe, jest niezwykle rozsądnym rozwiązaniem. Alternatywą jest skonfigurowanie front-endu, takiego jak Nginx, i zapewnienie tego ruchu proxy do poszczególnych pracowników, na przemian między pracownikami w celu przypisania nowych połączeń. Te dwa rozwiązania mają bardzo podobną charakterystykę wydajności. A ponieważ, jak wspomniałem powyżej, prawdopodobnie będziesz chciał, aby Nginx (lub alternatywa) przewyższał twoją usługę węzła, wybór tutaj jest naprawdę pomiędzy:
Współużytkowane porty: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
vs
Poszczególne porty: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
Prawdopodobnie istnieją pewne zalety konfiguracji poszczególnych portów (możliwość mniejszego sprzężenia między procesami, bardziej wyrafinowane decyzje dotyczące równoważenia obciążenia itp.), Ale zdecydowanie więcej pracy trzeba skonfigurować, a wbudowany moduł klastra jest niski - alternatywa złożoności, która działa dla większości ludzi.