Wie vergleicht sich ein Node.js-Server mit Nginx- oder Apache-Servern?

86

Ich habe kürzlich Node.js studiert und bin auf Material zum Schreiben einfacher Node.js-basierter Server gestoßen. Zum Beispiel das Folgende.

var express = require("express"),
http = require("http"), app;

// Create our Express-powered HTTP server
// and have it listen on port 3000
app = express();
http.createServer(app).listen(3000);

// set up our routes
app.get("/hello", function (req, res) {
    res.send("Hello World!");
});

app.get("/goodbye", function (req, res) {
    res.send("Goodbye World!");
});

Obwohl ich zu verstehen scheine, was im Code vor sich geht, bin ich durch die Terminologie etwas verwirrt. Wenn ich den Begriff Server höre, denke ich an Dinge wie Apache oder Nginx. Ich bin es gewohnt, sie als einen Container zu betrachten, der meine Webanwendungen aufnehmen kann. Wie unterscheidet sich der Node.js-Server vom Nginx / Apache-Server? Stimmt es nicht, dass ein Node.js-basierter Server (dh Code) immer noch in etwas wie Nginx platziert werden kann, um ausgeführt zu werden? Warum werden beide "Server" genannt?

Dankbar
quelle
2
Isn't it true that a Node.js based server (i.e. code) will still be placed within something like Nginx to run?Nein, das ist falsch
Jaromanda X
1
Technisch gesehen können Sie Ihre App ausführen und einen Knoten haben, der sie dem Client zur Verfügung stellt, der die Rolle des Webservers effektiv ausfüllt, aber Sie beißen wahrscheinlich mehr ab, als Sie kauen möchten. Ich habe kürzlich diesen großartigen Artikel zum Thema gelesen: nginx.com/blog/nginx-vs-apache-our-view
datafunk
1
Lassen Sie mich klarstellen, dass ich, als ich nach dem Unterschied zwischen den beiden fragte, NICHT über Apache gegen Nginx sprach. Ich habe über Node.js gegen Nginx gesprochen.
Dankbar
1
Lassen Sie sich vom Titel nicht irreführen. Wenn Sie den Artikel lesen, werden Sie verstehen, warum ich gesagt habe, dass Sie, obwohl Sie es selbst tun können, vielleicht nicht wollen ...
datafunk

Antworten:

127

Es ist ein Server, ja.

Eine node.js-Webanwendung ist genau wie Nginx oder Apache ein vollwertiger Webserver.

Sie können Ihre node.js-Anwendung tatsächlich ohne Verwendung eines anderen Webservers bereitstellen. Ändern Sie einfach Ihren Code in:

app = express();
http.createServer(app).listen(80); // serve HTTP directly

In der Tat verwenden einige Projekte node.js als Front-End- Load-Balancer für andere Server (einschließlich Apache).

Beachten Sie, dass node.js nicht der einzige Entwicklungsstapel ist, der dies tut. Webentwicklungs-Frameworks in Go, Java und Swift tun dies ebenfalls.

Warum?

Am Anfang war der CGI. CGI war in Ordnung und funktionierte einwandfrei. Apache würde eine Anfrage erhalten, feststellen, dass die URL eine CGI-App ausführen muss, diese CGI-App ausführen und Daten als Umgebungsvariablen übergeben, die Standardausgabe lesen und die Daten an den Browser zurücksenden.

Das Problem ist, dass es langsam ist. Es ist in Ordnung, wenn die CGI-App ein kleines statisch kompiliertes C-Programm war, aber eine Gruppe kleiner statisch kompilierter C-Programme schwer zu warten war. Also fingen die Leute an, in Skriptsprachen zu schreiben. Dann wurde es schwierig, dies aufrechtzuerhalten, und die Leute begannen, objektorientierte MVC-Frameworks zu entwickeln. Jetzt hatten wir Probleme - JEDE ANFRAGE muss all diese Klassen kompilieren und all diese Objekte erstellen, nur um etwas HTML bereitzustellen, auch wenn nichts Dynamisches zu bedienen ist (weil das Framework herausfinden muss, dass es nichts Dynamisches zu bedienen gibt).

Was ist, wenn wir nicht bei jeder Anfrage alle diese Objekte erstellen müssen?

Das dachten die Leute. Und aus dem Versuch, dieses Problem zu lösen, gingen mehrere Strategien hervor. Eine der frühesten bestand darin, Dolmetscher wie mod_phpin Apache direkt in Webserver einzubetten . Kompilierte Klassen und Objekte können in globalen Variablen gespeichert und daher zwischengespeichert werden. Eine andere Strategie bestand darin, eine Vorkompilierung durchzuführen. Eine weitere Strategie bestand darin, die Anwendung als regulären Serverprozess auszuführen und mit dem Webserver über ein benutzerdefiniertes Protokoll wie FastCGI zu kommunizieren.

Dann haben einige Entwickler einfach HTTP als App-> Server-Protokoll verwendet. Tatsächlich ist die App auch ein HTTP-Server. Dies hat den Vorteil, dass Sie kein neues, möglicherweise fehlerhaftes, möglicherweise nicht getestetes Protokoll implementieren müssen und Ihre App direkt über einen Webbrowser (oder auch häufig curl) debuggen können . Und Sie benötigen keinen modifizierten Webserver, um Ihre App zu unterstützen, sondern nur einen Webserver, der Reverse Proxy oder Weiterleitungen durchführen kann.

Warum Apache / Nginx verwenden?

Wenn Sie eine node.js-App bereitstellen, beachten Sie, dass Sie der Autor Ihres eigenen Webservers sind. Jeder potenzielle Fehler in Ihrer App ist ein direkt ausnutzbarer Fehler im Internet. Einige Leute fühlen sich (zu Recht) damit nicht wohl.

Wenn Sie eine Apache- oder Nginx-Schicht vor Ihrer node.js-App hinzufügen, steht Ihnen im Live-Internet eine kampferprobte, sicherheitsgehärtete Software als Schnittstelle zu Ihrer App zur Verfügung. Es fügt ein kleines bisschen Latenz hinzu (das Reverse Proxy), aber die meisten halten es für lohnenswert.

Dies war in den frühen Tagen von node.js der Standardratschlag. Heutzutage gibt es aber auch Websites und Webdienste, die node.js direkt dem Internet zugänglich machen. Das http.ServerModul ist jetzt im Internet ziemlich gut kampferprobt, um vertrauenswürdig zu sein.

Slebetman
quelle
1
Ich habe in ähnlichen SO-Threads gelesen, dass das Platzieren einer Nginx- oder Apache-Ebene vor Node "ihre nicht blockierende Natur beseitigt". Irgendwelche Gedanken dazu?
MrfksIV
3
@ MrfksIV Sowohl Nginx als auch Apache2 blockieren nicht. Tatsächlich haben sie Nonblocking implementiert, lange bevor node.js existierte. Verwenden Sie nicht Apache1
Slebetman
14

NodeJs erstellt einen eigenen Server. Wie Sie sehen können, ist die Terminologie ganz klar:

http.createServer(app).listen(3000);

Erstellen Sie einen Server und warten Sie auf HTTP-Anforderungen an Port 3000.

Wir haben nginx in einem unserer Projekte verwendet, aber es war eher ein Loadbalancer für mehrere NodeJS-Instanzen.

Nehmen wir an, Sie haben zwei NodeJS-Instanzen, die auf Port 3000 und 3001 ausgeführt werden. Jetzt können Sie sie weiterhin nginxals Server verwenden, um Ihre tatsächlichen httpAnrufe abzuhören port 80, und möchten Ihre Anfrage nodejsmöglicherweise an den Server oder einen anderen Server umleiten , eher wie einen loadbalancer. Sie können also immer noch alles verwenden, was Sie nginxbenötigen nodejs.

Eine gute Frage wurde hier schon gestellt .

Naeem Shaikh
quelle
1
Ich bin eigentlich nicht zu sehr auf Nginx selbst konzentriert. Ich habe mich über den Unterschied zwischen dem "Server" von node.js und den anderen "Servern" wie Apache oder Nginx gewundert. Ich konnte nicht verstehen, wie der enthaltene (dh Knotencode) mit dem Container (dh Apache) gleichgesetzt werden kann ... Aber ich denke, dieses Verständnis war falsch. Jetzt ist mir klar, dass der Code von node.js Port 3000 abhört, genau wie Apache Port 80 abhört. Ich denke, sie sind ähnlich. Es ist also wahr zu sagen, dass beide Server ihre eigenen Stärken und Schwächen haben?
Dankbar
2
createServer erstellt lediglich einen Überwachungsport. Es dient nichts.
Roger F. Gay
1
Was bringt es, wenn nodejs createServer verwenden, um einen Port abzuhören, wenn auf Anfrage an diesen Port nichts bereitgestellt wird? ... Daher ist es auf die eine oder andere Weise durch logische Erweiterung ein "Server", oder?
GG2
@ RogerF.Gay ... erstellt einen Listener an einem angegebenen Port und führt bei eingehender Anforderung eine Rückruffunktion aus. Das ist, was ich sagen würde, es schafft einen Server.
Naeem Shaikh
1
@Naeem Shaikh Es dient nichts. Es macht keinen Sinn, etwas aufzurufen, das nichts für einen Server bietet.
Roger F. Gay
1

Angenommen, es gibt ein Hotel namens Apache Hotel, das für jeden Kunden einen Kellner hat.

Sobald der Kunde einen Salat bestellt, geht der Kellner zum Küchenchef und sagt es ihm. Während der Küchenchef das Essen zubereitet, wartet der Kellner. Hier,

Chef => File System,

Waiter => Thread,

Customer => Event.

Auch wenn der Kunde Wasser bestellt, bringt der Kellner erst nach dem Servieren den Salat mit. Der Kellner wartet weiter, bis der Koch den Salat zubereitet. Dieser Zustand wird als Sperrzustand bezeichnet. Selbst wenn das Hotel wächst, sollte jeder Kunde unterschiedliche Kellner haben. Dies erhöht die Blockierung von Threads (Kellnern).

Wenn Sie jetzt zum Node Hotel kommen, gibt es nur noch einen Kellner für alle Kunden. Wenn der erste Kunde Suppe bestellt, teilt der Kellner dies dem Küchenchef mit und geht zum zweiten Kunden. Nachdem das Essen fertig ist, liefert der Kellner an den Kunden. Hier wird der Kunde nicht warten. Dieser Zustand wird als nicht blockierender Zustand bezeichnet. Der einzelne Kellner (Thread) bedient alle Kunden und macht sie glücklich.

Daher ist der Knoten, bei dem es sich um eine Single-Threaded-Anwendung handelt, sehr schnell.

Vamshi Krishna
quelle