Node.js
Node.js

Follow

Feb 24, 2017 – 14 min read

Dieser Artikel stammt von Tomislav Capan, technischer Berater und Node.js Enthusiast. Tomislav hat ihn ursprünglich im August 2013 im Toptal-Blog veröffentlicht – den Originalbeitrag finden Sie hier; der Blog wurde leicht aktualisiert. Das folgende Thema basiert auf der Meinung und den Erfahrungen des Autors.

Die steigende Popularität von JavaScript hat viele Veränderungen mit sich gebracht, und das Gesicht der Webentwicklung hat sich heute dramatisch verändert. Die Dinge, die wir heute im Web mit JavaScript auf dem Server und im Browser tun können, waren noch vor einigen Jahren schwer vorstellbar oder wurden in Sandbox-Umgebungen wie Flash oder Java Applets gekapselt.

Bevor Sie sich mit Node.js beschäftigen, sollten Sie sich über die Vorteile der Verwendung von JavaScript im gesamten Stack informieren, das die Sprache und das Datenformat (JSON) vereinheitlicht, so dass Sie Entwicklerressourcen optimal wiederverwenden können. Da dies eher ein Vorteil von JavaScript als von Node.js im Speziellen ist, werden wir hier nicht näher darauf eingehen. Aber es ist ein entscheidender Vorteil, wenn Sie Node.js in Ihren Stack integrieren.

Node.js ist eine JavaScript-Laufzeitumgebung, die auf der V8 JavaScript-Engine von Chrome aufbaut. Es ist erwähnenswert, dass Ryan Dahl, der Schöpfer von Node.js, das Ziel hatte, Echtzeit-Websites mit Push-Funktionen zu erstellen, „inspiriert von Anwendungen wie Gmail“. Mit Node.js gab er den Entwicklern ein Werkzeug an die Hand, mit dem sie im nicht-blockierenden, ereignisgesteuerten E/A-Paradigma arbeiten können.

In einem Satz: Node.js glänzt in Echtzeit-Webanwendungen, die Push-Technologie über Websockets einsetzen. Was ist daran so revolutionär? Nun, nach über 20 Jahren zustandslosem Web, das auf dem zustandslosen Request-Response-Paradigma basiert, haben wir endlich Webanwendungen mit Echtzeit-Zwei-Wege-Verbindungen, bei denen sowohl der Client als auch der Server die Kommunikation initiieren können, so dass sie frei Daten austauschen können.

Das steht im krassen Gegensatz zum typischen Web-Response-Paradigma, bei dem immer der Client die Kommunikation initiiert. Außerdem basiert alles auf dem offenen Web-Stack (HTML, CSS und JS), der über den Standard-Port 80 läuft.

Man könnte einwenden, dass wir dies schon seit Jahren in Form von Flash- und Java-Applets haben – aber in Wirklichkeit waren das nur Sandbox-Umgebungen, die das Web als Transportprotokoll nutzten, um an den Client geliefert zu werden. Außerdem wurden sie isoliert ausgeführt und liefen oft über nicht standardisierte Ports, die zusätzliche Berechtigungen und dergleichen erforderten.

Mit all seinen Vorteilen spielt Node.js jetzt eine entscheidende Rolle im Technologie-Stack vieler hochkarätiger Unternehmen, die auf seine einzigartigen Vorteile angewiesen sind. Die Node.js Foundation hat die besten Überlegungen, warum Unternehmen Node.js in Betracht ziehen sollten, in einer kurzen Präsentation zusammengefasst, die auf der Seite Case Studies der Node.js Foundation zu finden ist.

In diesem Beitrag werde ich nicht nur erörtern, wie diese Vorteile erreicht werden, sondern auch, warum Sie Node.js einsetzen sollten – und warum nicht – und dabei einige der klassischen Webanwendungsmodelle als Beispiele verwenden.

Wie funktioniert es?

Die Hauptidee von Node.js: Nicht blockierende, ereignisgesteuerte E/A zu verwenden, um angesichts datenintensiver Echtzeitanwendungen, die über verteilte Geräte laufen, leichtgewichtig und effizient zu bleiben.

Das ist ein Zungenbrecher.

Was es wirklich bedeutet, ist, dass Node.js keine neue Silberkugel-Plattform ist, die die Welt der Webentwicklung dominieren wird. Stattdessen ist es eine Plattform, die ein bestimmtes Bedürfnis befriedigt. Und das zu verstehen, ist absolut wichtig. Sie sollten Node.js auf keinen Fall für rechenintensive Operationen verwenden; in der Tat wird die Verwendung von Node.js für schwere Berechnungen fast alle seine Vorteile zunichte machen. Wo Node.js wirklich glänzt, ist beim Aufbau schneller, skalierbarer Netzwerkanwendungen, da es in der Lage ist, eine große Anzahl gleichzeitiger Verbindungen mit hohem Durchsatz zu verarbeiten, was einer hohen Skalierbarkeit gleichkommt.

Wie es unter der Haube funktioniert, ist ziemlich interessant. Im Vergleich zu traditionellen Web-Servicetechniken, bei denen jede Verbindung (Anfrage) einen neuen Thread erzeugt, der den Arbeitsspeicher des Systems beansprucht und schließlich an die Grenze des verfügbaren Arbeitsspeichers stößt, arbeitet Node.js mit einem einzigen Thread, der nicht blockierende E/A-Aufrufe verwendet, und kann so Zehntausende von gleichzeitigen Verbindungen unterstützen (die in der Ereignisschleife gehalten werden).

*Das Bild stammt aus dem ursprünglichen Blogbeitrag.

Eine schnelle Berechnung: Wenn man davon ausgeht, dass jeder Thread potenziell 2 MB Arbeitsspeicher mit sich führt, kommen wir auf einem System mit 8 GB RAM auf ein theoretisches Maximum von 4000 gleichzeitigen Verbindungen (Berechnungen aus Michael Abernethys Artikel „Just what is Node.js?“, der 2011 auf IBM developerWorks veröffentlicht wurde; leider ist der Artikel nicht mehr verfügbar), zuzüglich der Kosten für den Kontextwechsel zwischen Threads. Das ist das Szenario, mit dem man typischerweise bei traditionellen Web-Serving-Techniken zu tun hat. Indem all das vermieden wird, erreicht Node.js Skalierbarkeitsniveaus von über 1 Mio. gleichzeitigen Verbindungen und über 600.000 gleichzeitigen Websocket-Verbindungen.

Es stellt sich natürlich die Frage der gemeinsamen Nutzung eines einzigen Threads für alle Client-Anfragen, und dies ist ein potenzieller Fallstrick beim Schreiben von Node.js-Anwendungen. Erstens könnten umfangreiche Berechnungen den einzigen Thread von Node blockieren und Probleme für alle Clients verursachen (mehr dazu später), da eingehende Anfragen blockiert würden, bis die Berechnung abgeschlossen ist. Zweitens müssen die Entwickler sehr vorsichtig sein, damit eine Ausnahme nicht bis zum Kern (der obersten) Node.js-Ereignisschleife aufsteigt, was dazu führt, dass die Node.js-Instanz beendet wird (was das Programm effektiv zum Absturz bringt).

Die Technik, die verwendet wird, um zu vermeiden, dass Ausnahmen an die Oberfläche aufsteigen, besteht darin, Fehler als Callback-Parameter an den Aufrufer zurückzugeben (anstatt sie zu werfen, wie in anderen Umgebungen). Selbst wenn eine unbehandelte Ausnahme an die Oberfläche gelangt, wurden Werkzeuge entwickelt, um den Node.js-Prozess zu überwachen und die notwendige Wiederherstellung einer abgestürzten Instanz durchzuführen (obwohl man wahrscheinlich nicht in der Lage sein wird, den aktuellen Zustand der Benutzersitzung wiederherzustellen). Die gebräuchlichste Methode ist das Forever-Modul oder die Verwendung eines anderen Ansatzes mit den externen Systemwerkzeugen upstart und monit oder sogar nur upstart.

npm: Der Node Package Manager

Wenn man über Node.js spricht, sollte man auf keinen Fall die eingebaute Unterstützung für die Paketverwaltung mit dem npm-Tool vergessen, das standardmäßig mit jeder Node.js-Installation mitgeliefert wird. Die Idee der npm-Module ist der von Ruby Gems sehr ähnlich: eine Reihe von öffentlich verfügbaren, wiederverwendbaren Komponenten, die durch einfache Installation über ein Online-Repository mit Versions- und Abhängigkeitsmanagement verfügbar sind.

Eine vollständige Liste der paketierten Module kann auf der npm-Website gefunden oder über das npm-CLI-Tool aufgerufen werden, das automatisch mit Node.js installiert wird. Das Modul-Ökosystem ist offen für alle, und jeder kann sein eigenes Modul veröffentlichen, das dann im npm-Repository aufgeführt wird. Eine kurze Einführung in npm findet sich im Beginner’s Guide und Details zum Veröffentlichen von Modulen im npm Publishing Tutorial.

Einige der nützlichsten npm-Module sind heute:

  • express – Express.js, ein von Sinatra inspiriertes Webentwicklungs-Framework für Node.js und der De-facto-Standard für die meisten Node.js-Anwendungen, die es heute gibt.
  • hapi – ein sehr modulares und einfach zu verwendendes, konfigurationszentriertes Framework für die Erstellung von Web- und Service-Anwendungen
  • connect – Connect ist ein erweiterbares HTTP-Server-Framework für Node.js, das eine Sammlung von hochleistungsfähigen „Plugins“ bereitstellt, die als Middleware bekannt sind; dient als Basis für Express.
  • socket.io und sockjs – Serverseitige Komponente der beiden gängigsten Websocket-Komponenten, die es heute gibt.
  • pug (ehemals Jade) – Eine der populären Templating-Engines, inspiriert von HAML, ein Standard in Express.js.
  • mongodb und mongojs – MongoDB-Wrapper, um die API für MongoDB-Objektdatenbanken in Node.js bereitzustellen.
  • redis – Redis-Client-Bibliothek.
  • lodash (underscore, lazy.js) – Der JavaScript-Utility-Gürtel. Underscore begann das Spiel, wurde aber von einem seiner beiden Gegenstücke verdrängt, vor allem wegen der besseren Leistung und modularen Implementierung.
  • forever – Wahrscheinlich das häufigste Dienstprogramm, um sicherzustellen, dass ein bestimmtes Node-Skript kontinuierlich läuft. Hält Ihren Node.js-Prozess in der Produktion angesichts unerwarteter Ausfälle aufrecht.
  • bluebird – Eine voll ausgestattete Promises/A+-Implementierung mit außergewöhnlich guter Leistung
  • moment – Eine leichtgewichtige JavaScript-Datumsbibliothek zum Parsen, Validieren, Manipulieren und Formatieren von Datumsangaben.

Die Liste geht weiter. Es gibt tonnenweise wirklich nützliche Pakete, die allen zur Verfügung stehen (nichts gegen die, die ich hier ausgelassen habe).

Wo Node.js eingesetzt werden sollte

Chat ist die typischste Echtzeit-Mehrbenutzer-Anwendung. Von IRC (damals) über viele proprietäre und offene Protokolle, die auf nicht-standardisierten Ports laufen, bis hin zu der Möglichkeit, alles in Node.js mit Websockets zu implementieren, die über den Standard-Port 80 laufen.

Die Chat-Anwendung ist wirklich das beste Beispiel für Node.js: Es ist eine leichtgewichtige, datenintensive (aber wenig verarbeitende/berechnende) Anwendung mit hohem Datenverkehr, die über verteilte Geräte läuft. Es ist auch ein großartiger Anwendungsfall zum Lernen, da er einfach ist und dennoch die meisten Paradigmen abdeckt, die man jemals in einer typischen Node.js-Anwendung verwenden wird.

Lassen Sie uns versuchen darzustellen, wie es funktioniert.

Im einfachsten Szenario haben wir einen einzelnen Chatroom auf unserer Website, wo Leute hinkommen und Nachrichten in einer eins-zu-vielen (eigentlich alle) Weise austauschen können. Angenommen, wir haben drei Personen auf der Website, die alle mit unserem Message Board verbunden sind.

Auf der Serverseite haben wir eine einfache Express.js-Anwendung, die zwei Dinge implementiert: 1) einen GET ‚/‘ Request-Handler, der die Webseite mit dem Message Board und einem ‚Send‘-Knopf bedient, um die Eingabe neuer Nachrichten zu initialisieren, und 2) einen Websockets-Server, der auf neue Nachrichten wartet, die von Websocket-Clients gesendet werden.

Auf der Client-Seite haben wir eine HTML-Seite mit einigen Handlern eingerichtet, einen für das ‚Send‘-Knopf-Klick-Ereignis, der die eingegebene Nachricht abholt und über den Websocket sendet, und einen weiteren, der auf neue eingehende Nachrichten auf dem Websockets-Client wartet (d.h.,

Wenn einer der Clients eine Nachricht sendet, passiert Folgendes:

  • Der Browser fängt den Klick auf die Schaltfläche „Senden“ über einen JavaScript-Handler ab, nimmt den Wert aus dem Eingabefeld auf (d.h. den Nachrichtentext) und sendet ihn an den Client, den Nachrichtentext) und sendet eine Websocket-Nachricht über den Websocket-Client, der mit unserem Server verbunden ist (initialisiert bei der Initialisierung der Webseite).
  • Die serverseitige Komponente der Websocket-Verbindung empfängt die Nachricht und leitet sie mit der Broadcast-Methode an alle anderen verbundenen Clients weiter.
  • Alle Clients empfangen die neue Nachricht als Push-Nachricht über eine clientseitige Websocket-Komponente, die auf der Webseite läuft. Sie übernehmen dann den Inhalt der Nachricht und aktualisieren die Webseite direkt, indem sie die neue Nachricht an die Tafel anhängen.

Bild aus dem Original-Blog.

Dies ist das einfachste Beispiel. Für eine robustere Lösung könnten Sie einen einfachen Cache verwenden, der auf dem Redis-Speicher basiert. Oder in einer noch fortschrittlicheren Lösung eine Nachrichtenwarteschlange für die Weiterleitung von Nachrichten an Clients und einen robusteren Zustellungsmechanismus, der vorübergehende Verbindungsverluste abdeckt oder Nachrichten für registrierte Clients speichert, während diese offline sind. Aber unabhängig von den Verbesserungen, die Sie vornehmen, wird Node.js immer noch nach den gleichen Grundprinzipien arbeiten: Reagieren auf Ereignisse, Handhabung vieler gleichzeitiger Verbindungen und Aufrechterhaltung einer flüssigen Benutzererfahrung.

API AUF EINER OBJEKT-DB

Obwohl Node.js wirklich mit Echtzeitanwendungen glänzt, ist es eine ziemlich natürliche Passform für die Darstellung von Daten aus Objekt-DBs (z.B. MongoDB). JSON-gespeicherte Daten ermöglichen es Node.js, ohne Impedanzfehlanpassung und Datenkonvertierung zu funktionieren.

Wenn Sie zum Beispiel Rails verwenden, würden Sie JSON in binäre Modelle konvertieren und sie dann als JSON über HTTP zurückgeben, wenn die Daten von React.js, Angular.js usw. oder sogar von einfachen jQuery-AJAX-Aufrufen konsumiert werden. Mit Node.js können Sie Ihre JSON-Objekte einfach über eine REST-API für den Client zur Verfügung stellen. Außerdem müssen Sie sich nicht um die Konvertierung zwischen JSON und anderen Formaten kümmern, wenn Sie aus Ihrer Datenbank lesen oder schreiben (wenn Sie MongoDB verwenden). Zusammenfassend lässt sich sagen, dass Sie mehrere Konvertierungen vermeiden können, indem Sie ein einheitliches Daten-Serialisierungsformat für Client, Server und Datenbank verwenden.

QUEUED INPUTS

Wenn Sie eine große Menge an gleichzeitigen Daten empfangen, kann Ihre Datenbank zu einem Engpass werden. Wie oben dargestellt, kann Node.js die gleichzeitigen Verbindungen leicht selbst verarbeiten. Da der Datenbankzugriff jedoch eine blockierende Operation ist (in diesem Fall), treten Probleme auf. Die Lösung besteht darin, das Verhalten des Clients zu bestätigen, bevor die Daten wirklich in die Datenbank geschrieben werden.

Mit diesem Ansatz behält das System seine Reaktionsfähigkeit unter hoher Last bei, was besonders nützlich ist, wenn der Client keine feste Bestätigung für das erfolgreiche Schreiben der Daten benötigt. Typische Beispiele sind: die Protokollierung oder das Schreiben von Benutzerverfolgungsdaten, die in Stapeln verarbeitet und erst zu einem späteren Zeitpunkt verwendet werden, sowie Vorgänge, die nicht sofort reflektiert werden müssen (wie die Aktualisierung der Anzahl der „Likes“ auf Facebook), bei denen eine eventuelle Konsistenz (die in der NoSQL-Welt so häufig verwendet wird) akzeptabel ist.

Daten werden in eine Warteschlange gestellt, die durch eine Art von Caching- oder Message Queuing (MQ)-Infrastruktur (z. B., RabbitMQ, ZeroMQ) in eine Warteschlange gestellt und von einem separaten Datenbank-Batch-Write-Prozess oder rechenintensiven Backend-Diensten verarbeitet, die in einer leistungsfähigeren Plattform für solche Aufgaben geschrieben wurden. Ein ähnliches Verhalten kann mit anderen Sprachen/Frameworks implementiert werden, allerdings nicht auf der gleichen Hardware, mit dem gleichen hohen, gleichbleibenden Durchsatz.

Bild aus dem Originalartikel.

Kurz gesagt: Mit Node kann man die Schreibvorgänge in der Datenbank zur Seite schieben und sich später mit ihnen befassen, als ob sie erfolgreich gewesen wären.

DATA STREAMING

In traditionelleren Web-Plattformen werden HTTP-Anfragen und -Antworten wie isolierte Ereignisse behandelt; in Wirklichkeit sind sie Streams. Diese Beobachtung kann in Node genutzt werden.js, um einige coole Funktionen zu entwickeln. Zum Beispiel ist es möglich, Dateien zu verarbeiten, während sie noch hochgeladen werden, da die Daten über einen Stream eingehen und wir sie online verarbeiten können. Dies könnte für die Echtzeit-Audio- oder Video-Codierung und das Proxying zwischen verschiedenen Datenquellen (siehe nächster Abschnitt) genutzt werden.

PROXY

Node.js kann leicht als serverseitiger Proxy eingesetzt werden, der eine große Anzahl gleichzeitiger Verbindungen ohne Blockierung verarbeiten kann. Es ist besonders nützlich für das Proxying verschiedener Dienste mit unterschiedlichen Antwortzeiten oder das Sammeln von Daten aus mehreren Quellen.

Ein Beispiel: Betrachten Sie eine serverseitige Anwendung, die mit Ressourcen von Drittanbietern kommuniziert, Daten aus verschiedenen Quellen bezieht oder Assets wie Bilder und Videos in Cloud-Diensten von Drittanbietern speichert.

Obwohl es dedizierte Proxy-Server gibt, kann die Verwendung von Node stattdessen hilfreich sein, wenn Ihre Proxy-Infrastruktur nicht vorhanden ist oder wenn Sie eine Lösung für die lokale Entwicklung benötigen. Damit meine ich, dass Sie eine clientseitige Anwendung mit einem Node.js-Entwicklungsserver für Assets und Proxy-/Stubbing-API-Anfragen erstellen könnten, während Sie in der Produktion solche Interaktionen mit einem dedizierten Proxy-Dienst (nginx, HAProxy usw.) abwickeln würden.

BROKERAGE – STOCK TRADER’S DASHBOARD

Lassen Sie uns zurück zur Anwendungsebene kommen. Ein weiteres Beispiel, bei dem Desktop-Software dominiert, aber leicht durch eine Echtzeit-Web-Lösung ersetzt werden könnte, ist die Handelssoftware von Maklern, die zur Verfolgung von Aktienkursen, zur Durchführung von Berechnungen/technischen Analysen und zur Erstellung von Grafiken/Diagrammen verwendet wird.

Der Wechsel zu einer webbasierten Echtzeit-Lösung würde es den Maklern ermöglichen, problemlos den Arbeitsplatz oder die Arbeitsumgebung zu wechseln. Vielleicht sehen wir sie schon bald am Strand von Florida, Ibiza oder Bali.

APPLICATION MONITORING DASHBOARD

Ein weiterer gängiger Anwendungsfall, für den Node-with-Web-Sockets perfekt geeignet ist: Verfolgung von Website-Besuchern und Visualisierung ihrer Interaktionen in Echtzeit. Sie könnten Echtzeit-Statistiken von Ihren Nutzern sammeln oder sogar noch einen Schritt weiter gehen, indem Sie gezielte Interaktionen mit Ihren Besuchern einführen, indem Sie einen Kommunikationskanal öffnen, wenn sie einen bestimmten Punkt in Ihrem Trichter erreichen – ein Beispiel dafür finden Sie bei CANDDi.

Stellen Sie sich vor, wie Sie Ihr Geschäft verbessern könnten, wenn Sie wüssten, was Ihre Besucher in Echtzeit tun – wenn Sie ihre Interaktionen visualisieren könnten. Mit den Echtzeit-Zwei-Wege-Sockets von Node.js können Sie das jetzt.

SYSTEM-ÜBERWACHUNGS-DASHBOARD

Nun, lassen Sie uns die Infrastruktur-Seite der Dinge besuchen. Stellen Sie sich zum Beispiel einen SaaS-Anbieter vor, der seinen Nutzern eine Seite zur Service-Überwachung anbieten möchte (zum Beispiel die GitHub-Statusseite). Mit der Node.js-Ereignisschleife können wir ein leistungsfähiges webbasiertes Dashboard erstellen, das den Status der Dienste asynchron prüft und die Daten über Websockets an die Clients weiterleitet.

Mit dieser Technologie kann der Status sowohl interner (unternehmensinterner) als auch öffentlicher Dienste live und in Echtzeit gemeldet werden. Gehen Sie noch einen Schritt weiter und stellen Sie sich ein Network Operations Center (NOC) vor, das Anwendungen eines Telekommunikationsbetreibers, eines Cloud-/Netzwerk-/Hosting-Anbieters oder eines Finanzinstituts überwacht, die alle auf dem offenen Web-Stack laufen, der von Node.js und Websockets anstelle von Java und/oder Java-Applets unterstützt wird.

Hinweis: Versuchen Sie nicht, harte Echtzeitsysteme in Node.js zu bauen (d. h. Systeme, die konstante Antwortzeiten erfordern). Erlang ist wahrscheinlich die bessere Wahl für diese Art von Anwendungen.

SERVER-SIDE WEB APPLICATIONS

Node.js mit Express.js kann auch verwendet werden, um klassische Webanwendungen auf der Server-Seite zu erstellen. Dieses Request-Response-Paradigma, bei dem Node.js gerendertes HTML mit sich herumträgt, ist zwar möglich, aber nicht der typische Anwendungsfall. Es gibt Argumente, die für und gegen diesen Ansatz sprechen. Hier sind einige Fakten, die es zu berücksichtigen gilt:

Vorteile:

  • Wenn Ihre Anwendung keine CPU-intensiven Berechnungen hat, können Sie sie von oben bis unten in Javascript aufbauen, sogar bis hinunter zur Datenbankebene, wenn Sie JSON-Speicherobjekt-DB wie MongoDB verwenden. Dies erleichtert die Entwicklung (einschließlich der Einstellung) erheblich.
  • Crawler erhalten eine vollständig gerenderte HTML-Antwort, die weitaus SEO-freundlicher ist als, sagen wir, eine Single Page Application oder eine Websockets-App, die auf Node.js ausgeführt wird.

Vorteile:

  • Jede CPU-intensive Berechnung wird die Reaktionsfähigkeit von Node.js blockieren, so dass eine Threading-Plattform ein besserer Ansatz ist. Alternativ könnten Sie versuchen, die Berechnung zu skalieren(*).
  • Die Verwendung von Node.js mit einer relationalen Datenbank ist immer noch ziemlich mühsam (siehe unten für weitere Details). Tun Sie sich selbst einen Gefallen und nehmen Sie eine andere Umgebung wie Rails, Django oder ASP.Net MVC, wenn Sie versuchen, relationale Operationen auszuführen.

(*) Eine Alternative zu CPU-intensiven Berechnungen ist es, eine hoch skalierbare MQ-gestützte Umgebung mit Back-End-Verarbeitung zu erstellen, um Node als „Sachbearbeiter“ an der Front zu behalten, um Client-Anfragen asynchron zu bearbeiten.

SERVER-SIDE WEB APPLICATION WITH A RELATIONAL DATABASE BEHIND

Vergleicht man beispielsweise Node.js mit Express.js gegen Ruby on Rails, so fällt die Entscheidung klar zugunsten von letzterem aus, wenn es um den relationalen Datenzugriff geht.

Relationale DB-Tools für Node.js sind im Vergleich zur Konkurrenz noch recht unterentwickelt. Auf der anderen Seite bietet Rails automatisch ein Datenzugriffs-Setup direkt aus der Box zusammen mit DB-Schema-Migrations-Support-Tools und anderen Edelsteinen (Wortspiel beabsichtigt). Rails und die anderen Frameworks haben ausgereifte und bewährte Active Record oder Data Mapper Datenzugriffsschichten, die Sie schmerzlich vermissen werden, wenn Sie versuchen, sie in reinem JavaScript zu replizieren.(*)

Wenn Sie jedoch wirklich dazu neigen, ganz bei JS zu bleiben, sollten Sie sich Sequelize und Node ORM2 ansehen.

(*) Es ist möglich und nicht ungewöhnlich, Node.js nur als öffentliche Fassade zu verwenden, während Sie Ihr Rails-Backend und seinen einfachen Zugang zu einer relationalen DB behalten.

HEAVY SERVER-SIDE COMPUTATION/PROCESSING

Wenn es um schwere Berechnungen geht, ist Node.js nicht die beste Plattform. Nein, Sie wollen definitiv keinen Server für Fibonacci-Berechnungen in Node.js bauen. Im Allgemeinen macht jede CPU-intensive Operation alle Durchsatzvorteile zunichte, die Node mit seinem ereignisgesteuerten, nicht blockierenden E/A-Modell bietet, da alle eingehenden Anfragen blockiert werden, während der Thread mit Ihrer Zahlenberechnung beschäftigt ist.

Wie bereits erwähnt, ist Node.js single-threaded und verwendet nur einen einzigen CPU-Kern. Wenn es darum geht, Gleichzeitigkeit auf einem Multi-Core-Server hinzuzufügen, arbeitet das Node-Kernteam an einem Cluster-Modul. Sie können auch mehrere Node.js-Serverinstanzen ziemlich einfach hinter einem Reverse-Proxy über nginx laufen lassen.

Beim Clustering sollten Sie immer noch alle schweren Berechnungen auf Hintergrundprozesse auslagern, die in einer dafür geeigneteren Umgebung geschrieben wurden, und sie über einen Message-Queue-Server wie RabbitMQ kommunizieren lassen.

Auch wenn Ihre Hintergrundverarbeitung anfangs auf demselben Server ausgeführt wird, hat ein solcher Ansatz das Potenzial für eine sehr hohe Skalierbarkeit. Diese Hintergrundverarbeitungsdienste können einfach auf separate Worker-Server verteilt werden, ohne dass die Lasten der vorgelagerten Webserver konfiguriert werden müssen.

Natürlich würde man den gleichen Ansatz auch auf anderen Plattformen verwenden, aber mit Node.js erhält man den hohen Durchsatz an Anfragen pro Sekunde, über den wir gesprochen haben, da jede Anfrage eine kleine Aufgabe ist, die sehr schnell und effizient abgewickelt wird.

Abschluss

Wir haben Node.js von der Theorie bis zur Praxis besprochen, beginnend mit seinen Zielen und Ambitionen und endend mit seinen Vorzügen und Fallstricken. Wenn Leute Probleme mit Node haben, läuft es fast immer auf die Tatsache hinaus, dass blockierende Operationen die Wurzel allen Übels sind – 99% der Missbräuche von Node sind eine direkte Folge davon.

Erinnern Sie sich: Node.js wurde nie geschaffen, um das Problem der Rechenskalierung zu lösen. Es wurde geschaffen, um das I/O-Skalierungsproblem zu lösen, was es wirklich gut kann.