Aus Spaß wurde Ernst und Ernst ist jetzt drei Jahre alt. Das gilt auch für die serverseitige JavaScript-Plattform Node.js. Und nein, dieser Artikel beschäftigt sich nicht mit der Einführung in Node.js und Sie werden auch keinen Webserver in Node.js im Verlauf dieses Artikels programmieren. Nein, dieser Artikel enthält keine einzige Zeile Quellcode. Vielmehr möchte ich darauf eingehen, was Node.js ist und was nicht und auch klarstellen, dass diese Plattform nicht die „Silver Bullet“ der Webentwicklung ist, mit der sich sämtliche Ihrer Probleme lösen lassen.
Die Entwicklung von Node.js
Seitdem Ryan Dahl sein Projekt im November 2009 auf der JSConf vorstellte, ist einige Zeit vergangen und die Plattform hat sich von einem Experiment zu einer ernstzunehmenden Komponente für Webanwendungen entwickelt.
Node.js sollte ursprünglich ein Ansatz werden, mit dem Ryan Dahl eine Progressbar, also eine Visualisierung des Fortschritts, für Dateiuploads darstellen wollte. Die Wahl fiel nach etlichen Versuchen mit anderen, bereits existierenden Sprachen und Plattformen schließlich auf JavaScript. Hier existierten zwar bereits Lösungen wie beispielsweise Rhino, eine in Java implementierte Möglichkeit, um JavaScript-Code auszuführen. Eigentlich sollte Rhino Bestandteil eines neuen Browsers von Netscape sein, kann allerdings auch auf der Kommandozeile eines Servers verwendet werden.
JavaScript eignete sich nach Ansicht von Ryan Dahl besonders für die Umsetzung seiner Idee, da es in JavaScript zu diesem Zeitpunkt noch keinerlei Vorgaben neben der reinen JavaScript-Syntax gab. So existiert im Gegensatz zu Ruby, Java oder PHP in JavaScript keinerlei Vorgabe, wie beispielsweise auf Dateien zugegriffen werden soll. Und genau diese Abwesenheit von Vorgaben machte sich Ryan Dahl bei der Entwicklung von Node.js zunutze.
Die Komponenten von Node.js
Den Kern der Plattform bildet die V8 JavaScript Runtime von Chrome, dem bekannten Webbrowser von Google. Sie ist dafür zuständig, den JavaScript-Quellcode einer Applikation zu interpretieren und auszuführen. Die V8-Engine weist einige Optimierungen auf, um die Ausführung zu beschleunigen und den Verbrauch von Arbeitsspeicher durch Applikationen möglichst gering zu halten. Zu diesen Optimierungen zählen unter anderem die Generierung von Maschinencode, Hidden Classes oder ein Garbage Collector, der dafür sorgt, dass nicht mehr benötigte Objekte aus dem Arbeitsspeicher entfernt werden. Wie bereits erwähnt, macht die Engine recht wenige Vorgaben, wenn es über die Interpretation von JavaScript-Code hinausgeht. Zu diesem Zweck integrierte Ryan weitere Bibliotheken, die es Ihnen als Entwickler ermöglichen, serverseitige JavaScript-Applikationen zu implementieren. Eine wesentliche Komponente ist der sogenannte Eventloop. Dieser wurde in die Node.js-Plattform in Form von libev integriert. Die Aufgabe des Eventloops ist es, die Abarbeitung asynchroner Anfragen zu bearbeiten. Greifen Sie beispielsweise auf den Inhalt einer Datei zu, wird diese Anfrage mit einer, von Ihnen definierten Callback-Funktion an den Eventloop weitergegeben. Dieser leitet die Anfrage an das Betriebssystem weiter. Ihre Applikation wird inzwischen fortgesetzt. Ist der Lesevorgang beendet, wird der Eventloop benachrichtigt und der entsprechende Callback ausgeführt. Die Verwendung dieser Technologie erlaubt es Node.js, lediglich einen Thread für die Programmausführung zu verwenden, was Ihnen als Entwickler den Aufwand paralleler Programmierung über mehrere Threads hinweg erspart. Sie müssen sich also nicht über die Threadsicherheit von Ressourcen innerhalb Ihrer Anwendung kümmern. Der Eventloop alleine hilft Ihnen allerdings auch noch nicht bei der Behandlung von Schreib- und Leseoperationen. Hierfür wird libeio verwendet, eine Bibliothek für asynchrone I/O-Operationen.
Neben den bisher vorgestellten Bibliotheken kommen in Node.js noch etliche weitere Komponenten zum Einsatz. C-Ares kümmert sich beispielsweise um die asynchrone Auflösung von Servernamen in Ihrer Webapplikation. Da Node.js hauptsächlich im Bereich der Webentwicklung eingesetzt wird, ist das am meisten verwendete Kommunikationsprotokoll HTTP. Dieser Tatsache trägt die Verwendung eines eigenen HTTP-Parsers Rechnung. Ursprünglich war er fester Bestandteil der Node.js-Plattform, wurde im späteren Verlauf der Entwicklung in ein eigenständiges Projekt ausgelagert. Der Parser ist in C geschrieben und dient dazu, Anfragen und Antworten über HTTP auszulesen beziehungsweise zu erstellen.
Stabilisierung und Windows Node.js auf Windows
Node.js befindet sich mittlerweile in Version 0.8.16. Wie lange es wirklich noch dauern wird, bis schließlich eine Version 1.0 veröffentlicht wird, ist schwer zu sagen. Node.js hatte in der Vergangenheit immer damit zu kämpfen, dass die Plattform im Bereich der Enterprise Webapplikationen nicht wirklich ernst genommen wurde. Dies liegt allerdings mit unter daran, dass zwischen den einzelnen Versionen wie 0.4 und 0.6 oder aber 0.6 und 0.8 gravierende Änderungen vorgenommen wurden, was dazu führte, dass einige Applikationen auf Basis von Node.js überhaupt nicht mehr oder nur noch eingeschränkt funktionierten. Diese fehlende Verlässlichkeit macht es schwierig, umfangreichere Investitionen für Applikationen auf dieser Plattform zu rechtfertigen.
Dieses Problem und auch der Mangel an Unterstützung verschiedener Betriebssysteme wurde von den Entwicklern von Node.js während der Entwicklung sehr ernst genommen und führte im ersten Schritt zur Integration von libuv in der Version 0.6 von Node.js. libuv ist eine Bibliothek, die sicherstellen soll, dass Node.js eine bessere Plattformunabhängigkeit bietet. Vor Version 0.6 war es nicht ohne weiteres möglich, Node.js unter Windows zu betreiben. Der Einsatz von libuv führte dazu, dass die Bibliotheken libev und libeio austauschbar wurden. So konnte unter Windows IOCP verwendet werden. Diese Schnittstelle bietet ähnliche Möglichkeiten wie die Kombination von libev und libeio unter Unixsystemen. Mit diesem Schritt gelang Node.js schließlich auch der Sprung in die Windows-Welt. Die Schattenseite der Integration von libuv war eine erhebliche Destabilisierung der Node.js-Plattform. Im Verlauf der Entwicklung der Version 0.6 hielten zahlreiche Bugfixes und Stabilisierungen Einzug in die Plattform, die schließlich mit der Version 0.8 dazu führten, dass Sie Node.js wieder mit gutem Gewissen in Ihren Applikationen einsetzen können.
Und warum jetzt eigentlich Node.js?
In letzter Zeit hatte ich eine Diskussion mit einem meiner Kollegen, in der es darum ging, warum so viele Entwickler ihre Kommandozeilenwerkzeuge in Node.js umsetzen. Die einfache Antwort ist: weil es geht. Es gibt eigentlich keinen Grund, warum Node.js um ein Vielfaches besser sein sollte als beispielsweise Perl. Ganz im Gegenteil, Sie können sich eher darauf verlassen, dass klassische Scriptsprachen auf älteren Servern vorhanden sind als eine Installation von Node.js. Andererseits spricht auch nichts gegen den Einsatz von Node.js. Die eigentliche Stärke von Node.js liegt allerdings nicht in der Entwicklung von Kommandozeilentools, sondern in Webapplikationen und hier auch nicht in der Umsetzung kompletter Applikationen, sondern eher von gewissen Teilen derartiger Applikationen. Sie können Node.js am ehesten als eine Art Ergänzung zu bestehenden Technologien sehen. Setzen Sie beispielsweise eine Applikation in PHP um und haben die Anforderung, dass Ihre Applikation Echtzeitbenachrichtigungen an Ihre Clients schicken soll, können Sie für diesen Anwendungsfall Node.js einsetzen. Auch zur Implementierung leichtgewichtiger Webservices eignet sich Node.js hervorragend. Was Node.js nicht so gut kann, ist die Auslieferung statischer Inhalte wie Webseiten, Stylesheets oder Bilder. Hier sollten Sie auf Altbewährtes in Form von klassischen Webservern wie Apache oder Nginx zurückgreifen.
Wenn Sie sich jetzt die Frage stellen, warum Sie überhaupt Node.js einsetzen sollen, ist dies durchaus berechtigt. Diese Frage sollten Sie sich allerdings bei jeder Technologie und vor und während jedes Projekts stellen, das Sie umsetzen. Die Stärken von serverseitigem JavaScript liegen vor allem in der leichtgewichtigen Entwicklung und der guten Unterstützung asynchroner, eventgetriebener Programmierung. Außerdem sind Sie in guter Gesellschaft, wenn Sie Node.js verwenden. Unternehmen wie beispielsweise Microsoft, Yahoo und LinkedIn setzen ebenfalls Node.js ein.
Lesenswert: Spaß mit Node.js http://t.co/FkzuJ91Z
Node.js wozu und warum: RT @mayflowerphp: Lesenswert: Spaß mit Node.js http://t.co/FkIZq54r
Sehr gut geschriebener Beitrag! Ich muss allerdings bemerken, dass anders als überall angenommen wird, eine Node.js nicht zwigend single-theaded ist. Lediglich der Eventloop ist single-threaded, ansonsten kann eine Node.js Anwendung natürlich auch aus mehreren Threads bestehen. (je nach I/O-Operationen, usw.).
Ich habe versucht, dass mal auf meinen Blog darzustellen:
http://lets-get-nerdy.com/eventhandling-in-node-js/