t3n 29

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.

Sebastian Springer
Sebastian Springer

arbeitet seit mehreren Jahren beim PHP-Dienstleister Mayflower in München und ist dort derzeit als Projekt- und Teamleiter tätig. Dabei liegt sein Fokus auf der Entwicklung und Qualitätssicherung von dynamischen Web-Applikationen mit JavaScript und PHP.

Startseite
  • Seite:
  • 1
  • 2
  • 3

Bitte beachte unsere Community-Richtlinien

6 Reaktionen
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

asmuelle

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

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.

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.

Pascal192

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

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?

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden

Hey du! Schön, dass du hier bist. 😊

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team bestehend aus 65 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Danke für deine Unterstützung.

Digitales High Five,
Stephan Dörner (Chefredakteur t3n.de) & das gesamte t3n-Team

Anleitung zur Deaktivierung