2012-11-12 13 views
9

Powiedzmy, że buduję trójwarstwową stronę internetową, z Mongo DB na końcu i trochę naprawdę lekkim javascriptem w przeglądarce (powiedzmy po prostu walidacja na formularzach, może kilka wymyślnych formantów, które odpalają niektóre żądania AJAX).Czy plik Node.js powinien być używany do intensywnego przetwarzania?

Muszę wybrać technologię dla warstwy "środkowej" (moglibyśmy ją posegregować na podkategorie, ale ten szczegół nie jest tutaj głównym tematem, tylko ogólny wybór technologii), w którym chcę schrupać niektóre dane pierwotne wychodząc z DB i renderuj to do jakiegoś HTMLa, który popycham do przeglądarki. Dość typowa architektura WWW dla cienkich klientów.

Moim bezpiecznym wyborem byłoby po prostu zaimplementowanie tej warstwy pośredniej w Javie, używając bibliotek takich jak Jongo, aby porozmawiać z Mongo DB i być może Jackson z marszałkiem/niemiłosiernym JSONem, by porozmawiać z moimi wymyślnymi kontrolkami, gdy żądają AJAX. I trochę architektury szablonów Java do renderowania mojego kodu HTML na serwerze.

Jednak jestem naprawdę zaintrygowany ideą rzuca to wszystko przez okno i przy użyciu node.js tej warstwie pośredniej, z następujących powodów:

  • lubię Javascript (dobre części) i powiedzmy, że dla logiki biznesowej tej aplikacji byłaby bardziej ekspresyjna niż Java.

  • To javascript wszędzie. Nie trzeba przełączać się między językami, a nawet OO i funkcjonalnymi paradygmatami, pracując w dowolnym miejscu na stosie. Nie ma przekładu tłumaczeniowego między poziomami, JSON jest obsługiwany natywnie wszędzie.

  • Mogę ponownie użyć logiki sprawdzania poprawności na kliencie i serwerze.

  • Jeśli w przyszłości zdecyduję się na stronę klienta renderującą HTML w przeglądarce, mogę ponownie wykorzystać istniejące szablony za pomocą czegoś w stylu szkieletu z dość minimalnym wysiłkiem refaktoryzacji/ponownego testowania.

Jeśli jesteś w tym momencie i lubisz Węzeł, wszystkie powyższe będą wydawać się oczywiste. Czy powinienem wybrać Węzeł, prawda?

ALE ... to jest to, gdzie spada mi na myśl: jak wszyscy wiemy, Węzeł oparty jest na modelu jednowątkowego asynchronicznego serwera we/wy. Jest to świetne ze względu na moją skalowalność i wydajność w zakresie obsługi zapytań o dane, ale co z moją logiką biznesową? A co z renderowaniem mojego szablonu? Czy te rzeczy nie spowodują ogromnego wąskiego gardła dla wszystkich wniosków w pojedynczym wątku?

dwa oczywiste rozwiązania przychodzą do głowy, ale żaden z nich nie siedzi po prawej:

  1. Trzymaj „blokowania” logikę biznesową tam i po prostu użyć klastra instancji węzła i równoważenia obciążenia, zgłoszeń serwisowych w prawdziwej paraleli. Ok świetnie, więc dlaczego Węzeł nie jest po prostu wielowątkowy? Czy też zawsze był to pomysł, aby zachować prostotę głupstwa i uniknąć wielowątkowej złożoności w przypadku bazowym, dzięki czemu programiści mogą wykonać dodatkowe prace konfiguracyjne, jeśli pożądana jest wielordzeniowa moc obliczeniowa?

  2. Przechowuj pojedyncze wystąpienie węzła i nie blokuj go, po prostu wywołując niektóre implementacje java mojej logiki biznesowej działającej na innym, muti-threaded, serwerze aplikacji. Ok, ta opcja całkowicie niweczy każdy program, który wymieniłem używając Node (w rzeczywistości zwiększa złożoność w porównaniu z używaniem Javy), poza możliwymi wzrostami wydajności i skalowalności dla żądań CRUD do DB.

Co prowadzi mnie w końcu do punktu moje pytanie - jestem brakuje jakiś ogromny ważny element układanki Node, które właśnie dostałem moje fakty całkowicie błędne, czy węzeł po prostu nie nadają się do chrupania logikę biznesową na serwer? Innymi słowy, czy Węzeł jest przydatny do siedzenia nad bazą danych i obsługi wielu żądań CRUD w bardziej wydajny i skalowalny sposób niż w jakiejś innej implementacji, która blokuje I/O? I musisz wykonać całą swoją logikę biznesową na poziomie poniżej, a nawet po stronie klienta, aby utrzymać rozsądny poziom wydajności i skalowalności?

Biorąc pod uwagę całe zamieszanie wokół Węzła, wolałbym, żeby przyniósł więcej do stołu niż to. Chciałbym być przekonany, że jest inaczej!

+0

Powodem, dla którego węzeł jest jednokrotnym gwintem jest JavaScript we wszystkich jego obecnych wcieleniach (niezaplanowane lub inkarnacje "krawędziowe") jest pojedynczym wątkiem. Istnieje kilka wyjątków od tej reguły, takich jak webworkerzy w kliencie, ale nawet wtedy twój model wątków jest inny niż ten, do którego możesz być przyzwyczajony w innych językach. – Matt

+0

Dobrze, naprawdę nie miałem na myśli prawdziwie wielowątkowego, ponieważ w wątkach można udostępniać dane, miałem na myśli coś pokrewnego webworkerom - po prostu sposób na równoległe obsługiwanie żądań, bez wzajemnej wiedzy, z pudełko. Można to oczywiście osiągnąć poprzez tworzenie klastrów serwerów Node - moje pytanie brzmi, jaki jest przypadek użycia, w którym nie chciałbyś tego robić? Jakie rzeczywiste praktyczne zastosowanie ma serwer WWW z jednym węzłem? – davnicwil

Odpowiedz

7

W danym systemie masz N CPU Dostępne (1-64, czy cokolwiek N bywa). W dowolnej aplikacji wymagającej dużej mocy obliczeniowej, utkniesz z przepustowością cpusu N. Nie ma magicznego sposobu, aby to naprawić, dodając więcej niż N wątków/procesów/cokolwiek. Albo twój kod musi być bardziej wydajny, albo potrzebujesz więcej procesorów. Więcej wątków nie pomoże.

Jednym z mało doceniana faktów o wydajności wielu CPU jest to, że jeśli trzeba uruchomić N + 1 operacji obciążających procesor w tym samym czasie swoją przepustowość na CPU idzie w dół całkiem sporo. Proces intensywnie obciążający procesor zwykle utrzymuje się na tym CPU przez bardzo długi czas, zanim go zrezygnuje, głodując inne zadania bardzo źle. W większości przypadków blokowanie operacji wejścia/wyjścia i jednoczesne przełączanie zadań sprawia, że ​​nowoczesne wielozadaniowość systemu operacyjnego działa tak samo dobrze. Gdyby więcej codziennych zadań było związanych z procesorem, odkrylibyśmy, że potrzebujemy o wiele więcej procesorów w naszych maszynach niż obecnie.

Fajną rzeczą, którą Node.js wnosi do wydajności serwera, jest dokładne wykorzystanie każdego wątku. W idealnym przypadku kończy się to mniejszym przełączaniem zadań. To nie jest ogromny wygrać, ale po N wątki obchodzenia N * C połączenia asynchronicznie będzie miał przewagę wydajności nad N * C blokującego wątki działające na takiej samej liczbie procesorów. Ale dolna granica procesorów pozostaje taka sama: jeśli masz więcej niż jedną rzeczywistą pracę procesora, to poczujesz ból.

Podczas ostatniej wizyty w interfejsie API Node.js istniał sposób na uruchomienie serwera z jednym słuchaczem i jednym wątkiem roboczym na procesor. Jeśli możesz to zrobić, byłbym skłonny przejść z Node.js pod warunkiem, że spełnione są pewne zastrzeżenia:

  • Podejście JavaScript wszędzie kupuje ci prostotę. Jeśli chodzi o coś skomplikowanego, byłbym zaniepokojony asynchronicznym stylem programowania, czyniącym rzeczy trudniejszymi niż łatwiejszymi.
  • Przetwarzanie szablonów i inne zadania obciążające procesor nie są znacznie wolniejsze w Node.js niż w przypadku innych języków/platform.
  • Sterowniki bazy danych są niezawodne.

Jest jeden minus, że mogę zobaczyć:

  • Jeżeli awaria nitki, tracisz wszystkie połączenia są obsługiwane przez tego wątku.

Wreszcie, spróbuj pamiętać, że czas programisty jest na ogół droższy niż serwery lub przepustowość.

+0

Świetna odpowiedź. Sądzę więc, że tak naprawdę sprowadza się do korzystania z mniejszej liczby wątków (lub nawet jednego wątku) do nasłuchiwania i żądań serwisowych poprzez wyeliminowanie blokowania we/wy. To ma wiele sensu. Dziękuję za wskazanie potencjalnego wykorzystania wątków roboczych - właśnie o tym mówiłem, tj. Możliwość przeniesienia do puli wątków roboczych, gdy trzeba wykonać prawdziwe przetwarzanie, na przykład wywołanie zwrotne z odczytanego DB, podczas gdy utrzymywanie wirowania wątku odbiornika żądania. Masz rację oczywiście, że każda praca jest ostatecznie związana cps serwera, a prędkość V8 :-) – davnicwil

Powiązane problemy