Entwicklung & Design

Node.js: Das JavaScript-Framework im Überblick

Seite 3 / 3

Asynchrone Ausführung

Das zentrale Konzept von Node.js basiert also auf der asynchronen Abarbeitung in einem Single-threaded-Event-Loop, um aufwändige I/O-Operationen auszulagern. Bei eigenem Code ist man selbst dafür verantwortlich, Node.js nicht zu blockieren. Warum diese Überlegung durchaus relevant ist, zeigt ein einfaches Beispiel.

Synchrone Berechnung

require('http').createServer(function (req, res) {
    console.log('incoming request');
    var i = 0, x = 1;
    while(i++ < 1000000000) {
        x = 40 * 50 * i + 47;
    }
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World');
    console.log('request answered');
}).listen(1337, '127.0.0.1');

Listing 5

Mit diesem Skript wird ein einfacher Webserver erstellt. Bei einer Anfrage gibt er auf der Konsole „incoming request“ aus. Die anschließenden Berechnungen sollen aufwändige Vorgänge innerhalb des Skripts simulieren, bevor der Server eine Rückgabe an den Client erstellt und verschickt, sowie auf der Konsole „request answered“ ausgibt. Der große Nachteil dieses Skripts besteht darin, dass während der Beantwortung eines Requests keine weiteren Anragen beantwortet werden können, da der Server durch die Berechnung blockiert ist. Die Ausgabe bei zwei annähernd gleichzeitig abgesendeten Requests ist entsprechend synchron (Listing 6).

Konsolenausgabe bei synchroner Berechnung

$ node server.js
incoming request
request answered
incoming request
request answered

Listing 6

Um die Berechnungen asynchron durchzuführen, bietet Node.js das „child_process“-Modul. Dieses Modul erlaubt im Zuge einer Applikation, Kind-Prozesse zu erstellen, in die verschiedene Aufgaben ausgelagert werden können. Eine bidirektionale Kommunikation zwischen Eltern- und Kind-Prozess ermöglicht darüber hinaus Events und Callbacks, die ein blockierendes Warten auf Antworten unnötig machen.

Listing 7 zeigt, wie eine einfache Lösung des Problems aussehen könnte. Es besteht im Prinzip aus den gleichen Komponenten wie das Beispiel der synchronen Berechnung. Der einzige Unterschied
besteht darin, dass der rechenintensive Teil in einer eigenen Datei liegt und als separater Kind-Prozess ausgeführt wird.
Durch das Kommando „fork“ wird aus dem Inhalt der angegebenen Datei ein
Kind-Prozess erzeugt. Mittels „send“ und „ok“ erfolgt die Kommunikation
zwischen den beiden Prozessen. Sobald der Eltern-Prozess eine
Rückmeldung erhält, wird die Antwort an den Client
gesendet.

Asynchrone Berechnung

// server.js
require('http').createServer(function (req, res) {
    console.log('incoming request');
    var task = require('child_process').fork('someTask.js');
    task.on('message', function (response) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Hello World');
        console.log('request answered');
    });
    task.send({ start: true });
}).listen(1337, '127.0.0.1');

// someTask.js
process.on('message', function(m) {
    var i = 0, x = 1;
    while(i++ < 1000000000) {
        x = 40 * 50 * i + 47;
    }
    process.send('finished');
});

Listing 7

Die Ausgabe dieses Skripts, ebenfalls mit zwei annähernd gleichzeitig abgesetzten Requests, ist in Listing 8 zu sehen. Es zeigt deutlich das Ergebnis einer asynchronen Bearbeitung. Dabei werden beide Requests sofort angenommen und bearbeitet. Sobald die
Berechnung abgeschlossen ist, erfolgt die Rückmeldung an den Client. Auf diese Weise wird das Skript nicht unnötig blockiert und
Node.js kann die Ressourcen besser ausnutzen.

Konsolenausgabe bei asynchroner Berechnung

$ node server.js
incoming request
incoming request
request answered
request answered

Listing 8

Ausblick

Die beiden Beispiele im Umgang mit Node.js zeigen, wie mächtig die Plattform ist. Verfolgt man das Konzept der Asynchronität konsequent, können mit einer Node.js-Instanz sehr viele Client-Anfragen bedient werden. Verschiedene Benchmarks sprechen in diesem Zusammenhang von mehreren zehntausend, manche gar von hunderttausenden parallelen Anfragen.

Aller Leistung zum Trotz entfaltet Node.js seine wahre Stärke jedoch erst im Zusammenspiel mit anderen Technologien. So empfiehlt es sich etwa, statische Inhalte von einem Nginx-Server ausliefern zu lassen und über einen Proxy-Server die Anfragen an Node.js weiterzuleiten.

Ein weiteres denkbares Szenario ist der Einsatz von Node.js in Verbindung mit Request-basierten Skriptsprachen wie beispielsweise PHP, um deren Schwächen bei bidirektionaler Echtzeit-Kommunikation auszugleichen. Durch die Kombination könnte so die Schwäche des einen (PHP) durch die Stärke des anderen (Node.js) ausgeglichen werden.

Die letzte stabile Version von Node.js verbesserte die Geschwindigkeit im Vergleich zur Vorgängerversion noch einmal deutlich. Das liegt unter anderem an einer aktualisierten Version der V8-Engine und einer Reihe von Erneuerungen verschiedener Kern-Bibliotheken.

An seine Grenzen stößt Node.js lediglich bei Überskalierung. Ist eine Instanz von Node.js mit den Anfragen überfordert, gibt es aber die Möglichkeit, über eine intelligente Proxy-Lösung die Anfragen von Clients auf verschiedene Node.js-Server zu verteilen. Der Applikationsstatus kann dann in einer Datenbank wie beispielsweise Redis zwischen den einzelnen Servern gespeichert werden.

Insgesamt zeigen all diese Denkanstöße, dass Node.js mit seinen Fähigkeiten noch lange nicht am Ende ist. Die Einsatzmöglichkeiten sind heute noch nicht überschaubar, einzig eines ist bislang klar: JavaScript auf Serverseite ist keineswegs absurd.

Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

6 Kommentare
Seyreb
Seyreb

Frühes Entwicklungsstadium?
Was hat das mit dem Versionierungschema zu tun?
Node.js ommt auf jeder menge Seiten zum Einsatz, und das teilweie schon seit Jahren!
Habt ihr andere Artikel genauso schlecht recherchiert?

Antworten
Pascal192
Pascal192

Der Post ist doch an mehreren Stellen schon nicht mehr aktuell…

Antworten
Lars Budde

@Pascal Der Artikel stammt aus dem t3n-Magazin Nr. 29. Die Erstveröffentlichung war – wie du oben nachlesen kannst – am 28.08.2012. Möglicherweise erklärt das die fehlende Aktualität, die du bemängelst.

Antworten
nazeK
nazeK

Node.js ist defintiv ausgereift. Die vielen Änderungen der Funktionen und Methoden (und damit auch der Dokumentation), sind seit Ende letzten Jahres m.M.n. nicht mehr das Problem. Natürlich muss, im Gegensatz zu PHP oder Ruby, der Code zur Zeit noch regelmäßig auf die Funktionalität geprüft werden (wenn man Node.js aktualisiert), da nicht unbedingt eine 100%ige Abwärtskompatibilität gegeben sein muss. Aber es ist nicht mehr so dramatisch wie vor einem Jahr.

Node.js ist eine sehr attraktive Alternative (ja, Alternative) zu Ruby, PHP und co. Applikationen wie Calipso zeigen eindrucksvoll, was wirklich mit Node.js machbar ist. Ich bin gegenwärtig am überlegen, warum man noch bei PHP bleiben sollte. Besonders bei Anwendungen die höherer Last ausgesetzt sind und wo man auch nur eine Anwendung auf einem Host betreibt, gebe ich Node.js den Vorzug. Für multi-node.js-Umgebungen (also Server auf denen mehrere Instanzen bzw. Anwendungen laufen), habe ich bisher noch nicht das Tool gefunden, welches das Organisieren ebendieser Anwendungen bequem ermöglicht (es gibt einige Tools, bisher aber noch nicht so bequem, dass Lieschen Müller damit umgehen könnte). Da bleiben Ruby und PHP *noch* erste Wahl. Ich kann mir aber vorstellen, dass sich dies bald ändern könnte.

Was natürlich auch beachtet werden muss, ist die Schwerfälligkeit der Using-Community. Also jener Webmaster, Hoster und IT-Anbieter, die später Node.js einsetzten müssten. Das Beispiel Nginx zeigt ja, dass bessere Software nicht unbedingt ein Argument für einen Umstieg ist. Anders kann man die herrschende Dominanz von Apachewebservern nicht erklären. Ähnlich kann/wird es wohl auch Node.js gehen. Ein Tool für Nerds, Geeks & Enterprise-Entwickler.

Antworten
asmuelle
asmuelle

Ich habe zur Zeit 5 Webapplikationen im Einsatz, die skalieren deutlich besser als ihre Tomcat Vorgänger und sind sehr stabil.

Antworten
areanet
areanet

Wer mehr über die technische Umsetzung von node.js und Co. erfahren will, für den haben wir ein fünfteiliges Tutorial zum Thema „Entwicklung einer Echzeit-Multiscreen-App“ in unserem Blog zusammengestellt: http://www.app-agentur-bw.de/blog/multiscreen-tutorial-chat-mit-websockets-teil-1-einfuehrung

Antworten

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.