Was ist so anders an Node.js ereignisgesteuertem? Können wir das nicht in HttpAsyncHandler von ASP.Net tun?

72

Ich bin nicht sehr erfahren in der Webprogrammierung und habe noch nichts in Node.js codiert, nur neugierig auf den ereignisgesteuerten Ansatz . Es scheint gut zu sein.

Der Artikel erklärt einige schlechte Dinge, die passieren können, wenn wir einen threadbasierten Ansatz zur Bearbeitung von Anforderungen verwenden und stattdessen einen ereignisgesteuerten Ansatz wählen sollten. Bei Thread-basiert bleibt der Kassierer / Thread bei uns, bis unser Essen / unsere Ressource fertig ist. Im ereignisgesteuerten Zustand sendet uns die Kassiererin irgendwo aus der Anforderungswarteschlange, damit wir keine anderen Anfragen blockieren, während wir auf unser Essen warten. Um das Blockieren von Threads zu skalieren, müssen Sie die Anzahl der Threads erhöhen. Für mich scheint dies eine schlechte Entschuldigung dafür zu sein, Threads / Threadpools nicht richtig zu verwenden.

Könnte das mit IHttpAsyncHandler nicht richtig gehandhabt werden? ASP.Net empfängt eine Anfrage, verwendet den ThreadPool und führt den Handler (BeginProcessRequest) aus. Anschließend laden wir die Datei / Datenbank mit einem Rückruf. Dieser Thread sollte dann frei sein, um andere Anfragen zu bearbeiten. Sobald das Lesen der Datei abgeschlossen ist, wird der ThreadPool erneut in Aktion gesetzt und führt die verbleibende Antwort aus. Für mich nicht so anders, warum ist das nicht so skalierbar?

Einer der mir bekannten Nachteile des Thread-basierten ist, dass die Verwendung von Threads mehr Speicher benötigt. Aber nur mit diesen können Sie die Vorteile mehrerer Kerne nutzen. Ich bezweifle, dass Node.js überhaupt keine Threads / Kerne verwendet.

Kann mich jemand darauf hinweisen, was der eigentliche Vorteil der Verwendung von Node.js anstelle von "ereignisgesteuert" oder "threadbasiert" ist (bringen Sie nicht das Argument "weil es sich um Javascript und jeden Browser handelt ...") die vorhandene Technologie?

Das war eine lange Frage. Vielen Dank :)

Hendry Ten
quelle
Sie können dies interessant finden: ayende.com/blog/72705/node-cs
alun

Antworten:

66

Erstens ist Node.js kein Multithreading. Das ist wichtig. Sie müssen ein sehr talentierter Programmierer sein, um Programme zu entwerfen, die in einer Thread-Umgebung perfekt funktionieren. Fäden sind einfach hart.

Sie müssen ein Gott sein , um ein Thread-Projekt aufrechtzuerhalten, bei dem es nicht richtig entworfen wurde. Es gibt einfach so viele Probleme, die bei sehr großen Projekten schwer zu vermeiden sind.

Zweitens wurde die gesamte Plattform so konzipiert, dass sie asynchron ausgeführt werden kann. Haben Sie ein ASP.NET-Projekt gesehen, bei dem jede einzelne E / A-Interaktion asynchron war? Einfach ausgedrückt, ASP.NET wurde nicht für ereignisgesteuerte Anwendungen entwickelt.

Dann gibt es den Speicherbedarf aufgrund der Tatsache, dass wir einen Thread pro offener Verbindung haben und das gesamte Skalierungsproblem. Korrigieren Sie mich, wenn ich falsch liege, aber ich weiß nicht, wie Sie vermeiden würden, für jede Verbindung in ASP.NET einen neuen Thread zu erstellen.

Ein weiteres Problem ist, dass eine Node.js-Anforderung inaktiv ist, wenn sie nicht verwendet wird oder auf E / A wartet. Auf der anderen Seite schläft ein C # -Thread. Jetzt gibt es eine Begrenzung für die Anzahl dieser Threads, die schlafen können. In Node.js können Sie problemlos 10.000 Clients gleichzeitig parallel auf einem Entwicklungscomputer verwalten. Sie versuchen, 10k-Threads parallel auf einer Entwicklungsmaschine zu verarbeiten.

JavaScript selbst als Sprache erleichtert die asynchrone Codierung. Wenn Sie sich noch in C # 2.0 befinden, ist die asynchrone Syntax ein echtes Problem. Viele Entwickler werden einfach verwirrt sein, wenn Sie überall definieren Action<>und Function<>Rückrufe verwenden. Ein in einem Ereignis geschriebenes ASP.NET-Projekt kann von einem durchschnittlichen ASP.NET-Entwickler einfach nicht gewartet werden.

Wie für Fäden und Kerne. Node.js ist Single-Threaded und skaliert durch Erstellen von Prozessen mit mehreren Knoten. Wenn Sie einen 16-Kern haben, führen Sie 16 Instanzen Ihres node.js-Servers aus und haben einen einzelnen Node.js-Load-Balancer vor sich. (Vielleicht ein Nginx Load Balancer, wenn Sie wollen).

Dies alles wurde von Anfang an auf sehr niedrigem Niveau in die Plattform geschrieben. Dies war keine Funktionalität, die später auf der ganzen Linie eingeführt wurde.

Weitere Vorteile

Node.js hat viel mehr zu bieten als oben. Oben ist nur angegeben, warum die Behandlung der Ereignisschleife durch Node.js besser ist als mit asynchronen Funktionen in ASP.NET.

  • Performance. Es ist schnell. Wirklich schnell.
  • Ein großer Vorteil von Node.js ist die Low-Level-API. Sie haben viel Kontrolle.
  • Sie haben den gesamten HTTP-Server direkt in Ihren Code integriert und dann an IIS ausgelagert.
  • Sie haben den gesamten Vergleich zwischen Nginx und Apache.
  • Die gesamte C10K-Herausforderung wird vom Knoten gut verarbeitet, nicht jedoch vom IIS
  • Die Kommunikation mit AJAX und JSON fühlt sich natürlich und einfach an.
  • Echtzeitkommunikation ist eines der großartigen Dinge bei Node.js. Es wurde dafür gemacht.
  • Spielt gut mit dokumentbasierten nosql-Datenbanken.
  • Kann auch einen TCP-Server ausführen. Kann Dateischreibzugriff ausführen, kann jeden Unix-Konsolenbefehl auf dem Server ausführen.
  • Sie fragen Ihre Datenbank in Javascript ab, indem Sie beispielsweise CouchDB und Map / Reduce verwenden. Sie schreiben Ihren Client in JavaScript. Während der Entwicklung auf Ihrem Webstack gibt es keine Kontextwechsel.
  • Umfangreiche Community-gesteuerte Open-Source-Module. Alles in node.js ist Open Source.
  • Geringer Platzbedarf und fast keine Abhängigkeiten. Sie können die Quelle node.js selbst erstellen.

Nachteile von Node.js.

Es ist schwer. Es ist jung. Als erfahrener JavaScript-Entwickler habe ich Schwierigkeiten, eine Website mit Node.js zu schreiben, nur weil sie auf niedriger Ebene ausgeführt wird und ich über ein hohes Maß an Kontrolle verfüge. Es fühlt sich genauso an wie C. Viel Flexibilität und Kraft, um entweder für mich verwendet zu werden oder um mich aufzuhängen.

Die API ist nicht eingefroren. Es ändert sich schnell. Ich kann mir vorstellen, dass ich eine große Website in 5 Jahren komplett neu schreiben muss, da Node.js bis dahin geändert wird. Es ist machbar, Sie müssen sich nur bewusst sein, dass die Wartung auf den Websites von node.j nicht billig ist.

weiterführende Literatur

http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/

http://blip.tv/file/2899135

http://nodeguide.com/

Raynos
quelle
16
ASP.NET erstellt nicht bei allen Anforderungen einen Thread. Dafür ist der Thread-Pool vorgesehen.
Hendry Ten
8
Jede E / A-Aktion, auch die Aspx-Seite, kann bei Bedarf asynchron sein.
Hendry Ten
5
@HendryTen aber wenn Sie mit dem rechten 100 Kunden - Verbindung haben nun parallel dann gäbe es einen 100 Fäden oder zumindest n Fäden und 100 - n - Clients in einem Puffer warten. Asynchrone E / A ist der richtige Weg, dies zu tun. Eine der Möglichkeiten zum Ausführen asychroner E / A besteht darin, ereignisgesteuert zu sein. Sehen Sie dieses Video
Raynos
4
@ Raynos, und in node.js werden diese in der Warteschlange stehen? Es sollten nicht unbedingt 100 Threads vorhanden sein. Das war die richtige asynchrone Verwendung des Threads für. Nur einige Threads warten auf Anfragen, weitere auf asynchrone Arbeit / Anruf oder Rückruf usw.
Hendry Ten
12
"Fäden sind einfach hart." LOL. "Leistung. Es ist schnell. Sehr schnell." LOL "Als erfahrener JavaScript-Entwickler habe ich Schwierigkeiten, eine Website mit Node.js zu schreiben, nur weil es so einfach ist und ich die Kontrolle habe. Es fühlt sich genauso an wie C." LOL. Es gibt sicher etwas Qualitätshumor in dieser Antwort :)
kralyk
28

Es gibt viele Missverständnisse in Bezug auf node.js vs. ASP.Net und asynchrone Programmierung. Sie können E / A in ASP.NET nicht blockieren . Die meisten Benutzer wissen nicht, dass das .NET-Framework Windows-iocompletion-Ports darunter verwendet, wenn Sie Webdienstaufrufe oder andere E / A-gebundene Vorgänge mit dem Start- / Endmuster in .Net 2.0 und höher ausführen. E / A-Abschlussports ist die Art und Weise, wie das Windows-Betriebssystem nicht blockierende E / A unterstützt, sodass der App-Thread freigegeben wird, warum der E / A-Vorgang abgeschlossen wird. Interessanterweise verwendet node.js eine weniger optimale nicht blockierende E / A-Implementierung in Windows über Cygwin. Auf der Roadmap befindet sich eine neue Windows-Version, die unter Anleitung von Microsoft E / A-Vervollständigungsports verwendet. An diesem Punkt gibt es darunter keinen Unterschied.

Es ist auch möglich, nicht blockierende Datenbankaufrufe in ADO.NET durchzuführen. Beachten Sie jedoch ORM-Tools wie NHibernate und Entity Framework. Sie sind immer noch sehr synchron.

Synchrone E / A (Blockierung) machen den Steuerungsfluss viel klarer und sind aus diesem Grund populär geworden. Der Grund, warum Computerumgebungen Multithreading betreiben, hat nur oberflächlich damit zu tun. Es bezieht sich allgemeiner auf die gemeinsame Nutzung von Zeit und die Auslastung mehrerer CPUs.

Nur ein einziger Thread kann bei längeren Vorgängen zu Hunger führen, was sowohl mit E / A als auch mit komplexen Berechnungen zusammenhängen kann. Also, obwohl die Faustregel ein Thread pr ist. Wenn Sie nicht blockierende E / A-Vorgänge verwenden, sollten Sie dennoch eine ausreichende Thread-Pool-Größe berücksichtigen, damit einfache Anforderungen nicht durch komplexere Vorgänge ausgehungert werden, wenn solche vorhanden sind. Mit mehreren Threads können komplexe Vorgänge auch problemlos auf mehrere CPUs aufgeteilt werden. Eine Umgebung mit einem einzigen Thread wie node.js kann Multicore-Prozessoren nur durch mehr Prozesse und Nachrichtenübermittlung zur Koordinierung von Aktionen verwenden.

Ich persönlich habe noch kein überzeugendes Argument für die Einführung einer zusätzlichen Technologie wie node.js gesehen. Es mag gute Gründe geben, aber sie haben meiner Meinung nach wenig mit der Wartung einer großen Anzahl von Verbindungen über nicht blockierende E / A zu tun, da dies auch mit ASP.NET möglich ist.

BTW tamejs kann dazu beitragen, dass der Code Ihres nodejs besser lesbar ist, ähnlich wie beim neuen kommenden .Net Async CTP.

Codevater
quelle
Ja, ich glaube nicht, dass die Node-Community sich selbst einen Gefallen tut, indem sie drastische Leistungsverbesserungen behauptet. Es ist die wahre Stärke, kleineren Teams zu ermöglichen, sich schnell zu entwickeln, ohne die Leistung zu beeinträchtigen oder Ihre Optionen einzuschränken. + Yay! wenn Sie JavaScript mögen.
Erik Reppen
17

Es ist leicht, den kulturellen Unterschied zwischen den Communitys Node.js und ASP.NET zu unterschätzen. Sicher, IHttpAsyncHandler existiert und es gibt es seit .NET 1.0, also ist es vielleicht sogar gut, aber der gesamte Code und die Diskussion um Node.js beziehen sich auf asynchrone E / A, was bei .NET entschieden nicht der Fall ist. Möchten Sie LINQ To SQL verwenden? Sie können irgendwie , irgendwie. Willst du Sachen protokollieren? Vielleicht funktioniert "CSharp DotNet Logger" .

Also ja, IHttpAsyncHandler ist da und wenn Sie wirklich vorsichtig sind, können Sie möglicherweise einen ereignisgesteuerten Webdienst schreiben, ohne irgendwo über blockierende E / A zu stolpern, aber ich habe nicht wirklich den Eindruck, dass viele Leute ihn verwenden es (und es ist sicherlich nicht die beste Art, ASP.NET-Apps zu schreiben). Im Gegensatz dazu dreht sich bei Node.js alles um ereignisgesteuerte E / A, alle Codebeispiele, alle Bibliotheken und es ist die einzige Möglichkeit, wie Benutzer es verwenden. Wenn Sie also darauf wetten würden, welches ereignisgesteuerte E / A-Modell tatsächlich vollständig funktioniert hat, ist Node.js wahrscheinlich das Richtige für Sie.

Aaron Maenpaa
quelle
2
Ich denke, Sie nehmen Async IO zu ernst. Es ist cool, es macht die Dinge manchmal schneller. es macht die Dinge immer komplizierter. Ich denke, Sie sollten sich .Net 4.5 genauer ansehen ...
AK_
@AK_, aber sowohl asynchron als auch ereignisgesteuert sind für JS-Entwickler mit einer Menge Erfahrung in der Benutzeroberfläche eine Selbstverständlichkeit. Der größte Unterschied in den Kulturen, IMO, ist die Präferenz für Minimalismus gegenüber der Länge der Feature-Liste, sowohl in Bezug auf Sprache, Implementierung als auch in Bezug auf das typische Design von Bibliotheken / Tools. Diese Präferenz beruht auf jahrelangem Schreiben von Code für mehrere Plattformen, die sich nicht unbedingt darauf einigen, was Ihr Code tatsächlich bedeutet, und ich denke, dass er erfahrenen JS-Entwicklern in Node weiterhin gute Dienste leisten wird. Async mit der Formbarkeit von JS und dem Geschmack erstklassiger Funktionen bedeutet viel weniger Code in den Händen eines starken JS-Entwicklers.
Erik Reppen
1

Nach den aktuellen technologischen Verbesserungen und dem Lesen der folgenden Links ist es eine Frage des Fachwissens und der Auswahl der perfekten Mischung gemäß dem jeweiligen Szenario. NodeJS wird ausgereift und auf der ASP.NET-Seite haben wir ASP.NET MVC, WebAPI und SignalR usw., um die Dinge besser zu machen.

Node.js vs .Net-Leistung

http://www.salmanq.com/blog/net-and-node-js-performance-comparison/2013/03/ und

http://www.hanselman.com/blog/InstallingAndRunningNodejsApplicationsWithinIISOnWindowsAreYouMad.aspx

Vielen Dank.

Praveen Prajapati
quelle