wildlife

Apache access.log mit node.js in Realtime parsen und zur Weiterverabeitung in RabbitMQ queuen

// May 17th, 2013 // No Comments » // IT, Node.js, Tutorials

Für ein firmeninternes Projekt (nein, hier werden keine 'Internals' preisgegeben ;) ) werte ich Apache access.log Dateien aus. Dies geschieht aktuell mittels eines Cronjobs, welcher ein PHP Script startet und das Log Zeile für Zeile ausliest, die Daten via Regular Expressions und StringSplit parsed und anschließend in eine MySQL-Datenbank schreibt. Das Problem hierbei ist, dass sowohl die Dateien (Logrotation ist auf 15 Minuten eingestellt) als auch die Zeilen seriell bearbeitet werden und dies natürlich sehr lange dauert. Zwischenzeitlich habe ich mir bereits gearman angeschaut, um trotz der Verwendung mit PHP diese Prozesse zu parallelisieren, jedoch habe ich hierbei bereits nach kurzer Zeit die Flinte ins Korn geworfen.

Nachdem ich mich nun mittlerweile seit einiger Zeit mit Node.js beschäftigt habe und nach einer knappen Woche auch gut mit RabbitMQ und dem Node.js-Modul node-amqp zurechtkomme, kam mir eine neue Idee. Warum nicht das access.log in Echtzeit auslesen, neu hinzugekommene Zeilen in eine RabbitMQ Queue zu schreiben und dann mit mehreren Worker-Prozessen parallel zu parsen und in eine Datenbank zu schreiben. Somit müsste nicht mehr auf die nächste Log-Rotation (15 min) und die Fertigstellung des Parsing-Scripts gewartet werden und es stünden die Daten nahezu in Echtzeit zur Verfügung.

Hier also die ersten Schritte, um das neue Konzept umzusetzen: Weiterlesen...

Prozesse unter Linux anhand des Prozessnamen beenden

// May 7th, 2013 // No Comments » // IT, Tutorials

Dies ist vmtl. eher eine Notiz für mich, als ein ausgewachsener Artikel. Nichtsdestotrotz habe ich ab und an das Problem, dass sich PHP-Prozesse die über die CLI per Cron gestartet werden, nicht sauber beenden. Grundsätzlich sollte hier natürlich nach der Ursache des Problems gesucht werden, aber um erstmal wieder Herr über den Server und seine Prozesse zu werden, ist das Beenden dieser der erste Schritt.

Hierzu muss lediglich folgender Befehl ausgeführt werden:

 

Verwenden von mehreren GitHub Repositories in Jenkins

// May 6th, 2013 // No Comments » // IT, Tutorials

Für ein neues GitHub (Enterprise) Projekt wollte ich heute auf Jenkins einen neuen Job anlegen. Da ich bereits in der Vergangenheit für einen anderen Jenkins-Job einen SSH-Key erstellt habe, wollte ich diesen auch für das neue GitHub-Repository nutzen. Beim Hinzufügen des Deploy-Keys erschien jedoch folgende Fehlermeldung:

gh-key-already-in-use

Leider ist es scheinbar nicht möglich, einen SSH-Key für mehrere Repositories zu nutzen. Da es sich um GitHub:Enterprise handelt, war es außerdem nicht möglich einen extra Benutzer anzulegen, welcher einfach dem Projekt hinzugefügt hätte werden können. Nach kurzer Recherche bin ich auf diese Anleitung gestoßen, welche sowohl das Problem beschreibt als auch direkt eine Lösung bereitstellt.

Zuerst erstellt man für jedes Repository einen eigenen SSH-Key, bei welchem der Schlüssel am besten bereits den Namen des Projekts beinhaltet und somit später einfacher zu identifizieren ist:

Der Befehl sollte möglichst unter dem gleichen Benutzer ausgeführt werden, unter welchem der Schlüssel später verwendet werden soll (in meinem Fall "jenkins"), so dass dieser direkt in das .ssh Verzeichnis im Home erstellt wird. Damit später für jedes GitHub-Repository der korrekte Schlüssel benutzt wird, legt man im Verzeichnis die Datei config an und gibt einen virtuellen Host, den echten Host, den User mit welchem die Verbindung aufgebaut werden soll und den absoluten Pfad zum SSH-Key an.

In der Konfiguration von Jenkins gibt man nun anstelle von z.B.

folgendes an:

Bei dem Aufruf wird zuerst in der .ssh/config nach dem angebenen Hostnamen geschaut und anschließend werden die dort konfigurierten Einstellungen für diese Verbindung übernommen.

Dynamisches Setzen von NODE_ENV für Produktions- bzw. Entwicklungsumgebung mit Node.js

// May 5th, 2013 // No Comments » // IT, Node.js, Tutorials

In den meisten Fällen empfiehlt es sich, für Produktions- und Entwicklungsumgebungen unterschiedliche Konfigurationen zu wählen. Insbesondere ist hier das Logging zu nennen, da auf den Umgebungen, auf welchen entwickelt wird, meist mehr Informationen während der Ausführung benötigt werden, als auf Produktivumgebungen.

Grundsätzlich ist die Empfehlung, die Umgebungsvariable NODE_ENV im Betriebssystem zu setzen. Dies funktioniert jedoch nur dann, wenn das entsprechende System grundsätzlich nur für Produktion oder Entwicklung genutzt wird. Für das letzte Testen von Änderungen vor dem 'Release' verwende ich jedoch das gleiche System, auf welchem später die Anwendung auch produktiv läuft, um Betriebssystem-abhängige Fehler auszuschließen (siehe z.B. diesen Beitrag). Würde ich also auf diesem System für die Umgebungsvariable NODE_ENV auf 'production' setzen, würde auch das Testing ohne erweitertes Logging durchgeführt. Hier macht es also Sinn, die Variable dynamisch anhand von bestimmten Kriterien zu setzen und diese dann zu nutzen, um die Umgebung und somit die Konfiguration zu bestimmen.

Da ich (bisher) grundsätzlich unter Windows entwickle, das Produktivsystem jedoch auf Linux läuft, ist das erste Kriterium bereits klar. Da auf dem Produktivsystem jedoch auch das letzte Testing läuft muss hier nochmals unterschieden werden. Glücklicherweise läuft dieses immer in einem Verzeichnis, welches 'dev' enthält. Somit ist auch das zweite Kriterium festgelegt. Hier der Code dazu: Weiterlesen...

node.js – Probleme mit cluster modul unter Ubuntu

// May 4th, 2013 // 1 Comment » // IT, Node.js, PHP / Javascript

Vor ca. einer Woche habe ich angefangen mit Node.js zu arbeiten. Grund hierfür ist, dass ich für das eine oder andere Projekt Daten in Echtzeit übertragen möchte. Da die Datenübertragung, wie z.B. bei PHP bzw. Web 2.0 Projekten, nicht nur vom Client aus initiiert werden sondern der Server diese beim Aktualisieren der Datensätze zum Client pushen soll, bin ich auf Socket.io gestoßen. Hier wird u.a. eine eigene Websocket-Implementierung verwendet, welche bidirektionale Kommunikation zwischen Server / Backend und Client ermöglicht. Dies funktioniert sogar mit nahezu allen Browsern, da auf ältere / alternative Tranport-Mechanismen, wie z.B. gewöhnliche Websockets, flashsocket, jsonp-polling, etc., automatisch ausgewichen wird.

Da diese Projekte voraussichtlich größer und somit eine vermeintlich hohe Anzahl an parallelen Socket-Verbindungen bedienen müssen, habe ich mir das Cluster-Modul von Node.js angeschaut und in meine Projekte implementiert. Unter Windows, für welches eine entsprechende Portierung vorliegt, lief meine app.js Problemlos. Nach dem Deploy auf ein Staging-System, konnte die app.js nicht mehr gestartet werden, da "cluster.worker" scheinbar nicht mehr definiert war. Auch Versuche mit anderen Cluster-Modulen schlugen fehl.

Nachdem ich die Modul-Versionen unter Windows und Linux verglichen habe und keine Unterschiede feststellen konnte, habe ich im #node.js Channel im Freenode-IRC Hilfe gesucht. Nachdem sich einige den Code angeschaut haben (vielen Dank insbesondere an geNAZt (Google+ / Twitter), jedoch auch keine gravierenden Fehler gefunden haben, bin ich vorhin auf den Fehler gest0ßen:

Während ich unter Windows mittels dem, auf der Website bereitgestellten Installer, die neueste Version (0.10.5) von Node.js installiert habe, war auf dem Ubuntu noch eine Uralt-Version installiert. Dies liegt daran, dass in den normalen APT-Repositories lediglich das Paket nodejs-dev in der Version 0.6.12 vorhanden ist, welche nicht das neueste Cluster-Modul beinhaltet. Um die neueste Version zu erhalten, müssen zuerst folgende Schritte ausgeführt werden:

  • python-software-properties ist für den Befehl add-apt-repository erforderlich und ist scheinbar standardmäßig nicht installiert
  • anschließend wird das Repository ppa:chris-lea/node.js hinzugefügt und
  • ein Update der Repositories durchgeführt
  • zuletzt installiert man dann das Paket nodejs, welches nun in der neuesten Version (0.10.5) vorliegt.

2013-05-04_15-25-25

Nach dem Starten der App und dem Aufbau einer Socket-Verbindung vom Client / Browser, wird nun die ID des entsprechenden Workers korrekt angezeigt.

Eigene Subdomain für SSL Verschlüsselung mit Codeigniter

// April 2nd, 2013 // No Comments » // Blog / Website, IT, Tutorials

Ich möchte für ein neues Web-Projekt CloudFlare nutzen, welcher nahezu transparent Caching, CDN-Funktionalität als auch DDoS-Schutz bietet. Da das Projekt jedoch noch in den Kinderschuhen steckt, wäre die Pro-Variante mit einem Preis von 20$ / Monat etwas übertrieben. Einer der Nachteile der kostenfreien Version ist jedoch, dass SSL nicht unterstützt wird und alle Besucher welche die Seite über SSL (https) aufrufen würden, bekämen eine Fehlermeldung. Da jedoch Anmeldedaten (Benutzername und Passwort) übertragen werden sollen, wäre mir zumindest eine optionale Möglichkeit der Verschlüsselung sehr recht.

Ich habe mich daher für die folgende Lösung entschieden: standardmäßig wird die Seite über die normale Domain aufgerufen, welche über CloudFlare geschützt wird. Möchte ein Besucher jedoch explizit SSL-Verschlüsselung nutzen, wird er auf die Subdomain "secure.domain.de" umgeleitet, welche per SSL geschützt ist (hierauf gehe ich genauer ein, sobald die Domain bei einem neuen Provider und die Konfiguration bei CloudFlare abgeschlossen ist).

Weiterlesen...