The way to Go

Lange Zeit waren die Auftragnehmer der Raumfahrt große Rüstungskonzerne mit eingefahrenen Strukturen und dem entsprechenden Produkten. Die Raketen waren bspw. nicht gerade dazu gedacht, sie wieder zu verwenden. Wahrscheinlich konnte sich kaum einer der Auftraggeber vorstellen, dass das auch ganz anders geht. Und dann kam Elon Musk und hat “mal eben” SpaceX auf die Beine gestellt… und dann gingen viele Dinge auf einmal viel besser. So ähnlich auch in unserer Branche…

Lange Zeit gab es zwar maschinennahe Programmiersprachen, aber diese waren umständlich in der Handhabung – insbesondere im Hinblick auf die parallele Ausführung mehrerer Aufgaben. Die konstante Größe der Thread-Stacks limitierte zusätzlich die Anzahl der Threads, so dass bspw. das in C++ geschriebene Icinga 2 aktuell die E/A auf einige wenige Threads verteilen muss. Seit 2009 gibt es immerhin NodeJS, das gut und gerne viele E/A-Aufgaben parallel ausführt, aber auch nur diese – für Rechenoperationen steht nur ein Thread zur Verfügung. Zudem sind die Typen und Funktionen dynamisch und damit nicht so maschinennah und performant wie bspw. in C++. Und da saßen die Programmierer bis 2012 zwischen diesen zwei Stühlen. Und dann hat Google 2012 die erste stabile Version von Go veröffentlicht… und damit gingen viele Dinge auf einmal viel besser. So auch mittlerweile bei NETWAYS

Und was macht dieses Go jetzt besser als alle anderen?

Wie mein Kollege Florian sagen würde: “So einiges.” Aber Scherz beiseite…

Go ist maschinennah – d.h. die Typen und Funktionen sind allesamt statisch und werden wie auch bei bspw. C++ im voraus in Maschinencode umgewandelt – mehr Performance geht nicht.

Go ist einfach (obwohl es maschinennah ist). Die Datentypen sind zwar statisch, also explizit, aber deren Angabe ist nur so explizit wie nötig:

type IcingaStatus struct {
   Name, Description string
}
 
var IcingaStatusSet = map[uint8]IcingaStatus{
   0: {"OK",       "Alles im grünen Bereich"},
   1: {"WARNING",  "Die Ruhe vor dem Sturm"},
   2: {"CRITICAL", "Sämtliche Infrastruktur im Eimer"},
   3: {"UNKNOWN",  "Mein Name ist Hase, ich weiß von nichts"},
}

Im gerade gezeigten Beispiel muss der Datentyp der Map-Variable nur einmal angegeben werden. Weder die Typen der enthaltenen Werte, noch deren Felder müssen angegeben werden – sie werden vom Typ der Map abgeleitet. Wer befürchtet, den Überblick zu verlieren, kann auf die IDE GoLand zurückgreifen:

Go ist relativ sicher vor Unfällen (obwohl es maschinennah ist). Bei Zugriff auf eine Stelle eines Arrays, die gar nicht existiert oder unzulässiger Umwandlung von Zeiger-Datentypen wirft Go einen Fehler, um Schäden durch Programmierfehler abzuwenden:

type Laptop struct {
    DvdDrive uint32
}
 
func (l *Laptop) DoSomethingUseful() {
}
 
type SmartPhone struct {
    SimSlot uint16
}
 
func (s *SmartPhone) DoSomethingUseful() {
}
 
type Computer interface {
    DoSomethingUseful()
}
 
func main() {
    var computers = []Computer{&Laptop{}, &Laptop{}, &Laptop{}}
    _ = computers[3]
 
    var computer Computer = &Laptop{}
    _ = computer.(*SmartPhone)
}

Go erledigt von sich aus E/A-Aufgaben effizient (obwohl es nicht NodeJS ist). Aufgaben werden in Go nicht über Threads parallelisiert, sondern über sog. Go-Routinen (das gleiche in grün). Diese werden von Go selbst auf die eigentlichen Threads verteilt. Wenn eine Go-Routine eine blockierende E/A-Operation ausführt, wird diese transparent im Hintergrund vollzogen und eine andere Go-Routine beansprucht währenddessen den Thread.

Der Himmel ist die Grenze der Parallelisierung dank Scheduler und dynamischer Stack-Größe. Die o.g. Verteilung von Go-Routinen auf Threads verantwortet der sog. Scheduler von Go. Dies führt dazu, dass “zu” viele parallele Aufgaben sich und dem Rest des Systems nicht im Weg stehen. Zudem beansprucht jede Go-Routine nur soviel RAM wie sie auch wirklich braucht, d.h. eigentlich kann ein Programmierer so viele Go-Routinen starten wie er lustig ist (Beispiel). “Eigentlich” ist genau das richtige Stichwort, denn trotzdem sollte jeder Einzelfall für sich betrachtet werden. Ansonsten macht das OS irgendwann git push --feierabend (Beispiel).

Go geht einfach (daher kommt wahrscheinlich auch der Name). Im Gegensatz zu etablierten maschinennahen Sprachen muss ich mich nicht darum kümmern, dass libfoobar23.dll an der richtigen Stelle in der korrekten Version vorliegt. Das Ergebnis eines Go-Kompiliervorgangs ist eine Binary, die nichtmal gegen libc gelinked ist:

root@576214afd7e6:/# cat example.go
package main

func main() {
}
root@576214afd7e6:/# go build -o example example.go
root@576214afd7e6:/# ./example
root@576214afd7e6:/# ldd ./example
not a dynamic executable
root@576214afd7e6:/#

Alles kann, nichts muss. Go muss ja nicht von heute auf Morgen in sämtlichen Applikationen Anwendung finden. Man kann auch mit einem einzigen Programm anfangen, das nicht heute, jetzt und eigentlich schon vorgestern fertig sein muss. Und selbst wenn nicht alles beim ersten Mal klappt, bieten wir Ihnen gerne maßgeschneidertes Consulting an.

Alexander Klimov

Autor: Alexander Klimov

Alexander hat 2017 seine Ausbildung zum Developer bei NETWAYS erfolgreich abgeschlossen. Als leidenschaftlicher Programmierer und begeisterter Anhänger der Idee freier Software, hat er sich dabei innerhalb kürzester Zeit in die Herzen seiner Kollegen im Development geschlichen. Wäre nicht ausgerechnet Gandhi sein Vorbild, würde er von dort aus daran arbeiten, seinen geheimen Plan, erst die Abteilung und dann die Weltherrschaft an sich zu reißen, zu realisieren - tut er aber nicht. Stattdessen beschreitet er mit der Arbeit an Icinga Web 2 bei uns friedliche Wege.

How css-tricks improved my work life

My relationship with CSS is some kind of a love-hate one and I think that is a sentiment a lot of web-devs share with me.
My biggest issue with it is, that it is really counterintuitive and most of the time it feels a bit like solving puzzles to make things align the way you want it to.

and oftentimes it feels a lot like

Properties that mean the same thing being worded inconsistently – I’m looking at you…

vertical-align: middle;
text-align: center;

And there is also some questionable naming with ‘grey’ (#808080) being darker than ‘darkgrey’ (#a9a9a9)…

In general there are too many quirks you need to just know. Unless you work with it every day, you need to google every second line in order to write your stylesheets.
There you can find all sorts of guidelines, help, blogposts with a nice mix of bad-practices and outdated information.

What helped me a lot is the website css-tricks.

(more…)

Jennifer Mourek

Autor: Jennifer Mourek

Jennifer (von eigentlich jedem nur "Feu" genannt) verbrachte ihre Kindheit im schönen Steigerwald und kämpfte sich bis zum Abitur durch die Schule. Seit September 2016 unterstützt sie nun im Rahmen ihrer Ausbildung zum Fachinformatiker die Development Abteilung bei Netways und widmet sich dort dem Web Development. Ihre Freizeit verbringt sie hauptsächlich in den virtuellen Welten von 'Dota 2' und diversen anderen Games, an der Kletterwand in der Boulderhalle oder damit ihren Freunden und Kollegen auf die Nerven zu gehen.

Außerhalb von NETWAYS: Projektwoche in der Berufsschule

Heute möchte ich einen Blick außerhalb der betrieblichen Ausbildung werfen und ein wenig über die Projektwoche in der Berufsschule berichten. Alle Auszubildenden, die die Berufsschule B3 in Fürth im Zweig Fachinformatik Systemintegration oder Anwendungsentwicklung besuchen, führen dort am Ende des 2. Ausbildungsjahres eine Projektwoche durch.

Innerhalb dieser Projektwoche arbeiten die Schüler einer Klasse in Gruppen von 12 – 15 Mitgliedern zusammen. Dabei wird vor allem darauf geachtet, dass die Stärken der Schüler gleichmäßig auf die Gruppen verteilt werden.

Das Projekt selbst bestand aus der Simulation eines Kundenauftrages an eine Firma, die sowohl die Umsetzung von IT-Infrastrukturen als auch Software-Entwicklung bietet. Die Belegschaft der Firma wurde dann wie folgt auf die Mitschüler aufgeteilt:

  • Abteilung Management: 3 Schüler
  • Abteilung Infrastruktur: 3 Schüler
  • Abteilung Entwicklung: 6 Schüler

Die Gewichtung ergab sich aus der Analyse des Lastenheftes, das vom Lehrerkollegium zuvor ausgearbeitet und ausgehändigt wurde. Darin ging es darum, dass für den Kunden eine Infrastruktur und Software aufgebaut werden soll, mit der der Kunde sämtliches IT-Inventar in seinen Räumlichkeiten verwalten kann. Der Kunde selbst wurde dabei durch unsere Schule und einen Teil des Lehrerkollegiums dargestellt. Folgende Punkte waren dabei besonders von Bedeutung:

  • Netzwerk mit VLANs (Trennung von Schul- und Administrationsnetzwerk) mit Access Points für WLAN
  • Web- und Datenbankserver, auf denen die Inventarisierungssoftware laufen soll
  • Mit der Software müssen folgende Aktionen machbar sein:
    • Auflisten von Inventar
    • Ändern, Löschen und Hinzufügen von Inventar
    • Zuordnung von Inventar zu Räumen und Klassenzimmern
    • Login mit User/Passwort und Vergabe von Rechten (Admin oder User)
  • Einrichten von Clients für die Nutzung des Webfrontends der Software
    • Aufrufbar über Browser
    • Ergonomie muss beachtet werden
  • Erstellung eines Pflichtenheftes, einer Kundendokumentation und eines Wartungsvertrages
    • Pflichtenheft und Wartungsvertrag muss von den Lehrkräften abgenommen werden
    • Kundendokumentation soll als Benutzerhandbuch fungieren
  • Abschließende Projekt-Präsentation vor Publikum mit abschließender Fragerunde
  • Zeitlicher Rahmen: Montag bis Donnerstag, Umsetzung des Projektes mit freier Zeiteinteilung, Freitag morgen Präsentation

Nachdem wir den Montagvormittag damit verbrachten, die Aufgabenstellung durchzuplanen, setzten wir im Laufe der Woche die folgenden Schritte um:

  • Erstellung Pflichtenheft
  • Aufbau Netzwerk
  • Aufbau LAMP-Stack auf Server
  • Aufbau der MySQL-Datenbank
  • Erstellung der Core Software aus php und javascript
  • Erstellung des Webfrontends mit html und php
  • Erstellung Wartungsvertrag
  • Erstellung und Planung Projekt-Präsentation
  • Ausführliches Testen der einzelnen Komponenten
  • Fehlersuche, Debugging und Korrekturen
  • Erstellung Kundendokumentation, direkt aufrufbar über die Hilfe-Funktion in der Software

Mit dem Ergebnis aus dieser Woche konnten wir dann auch unsere Lehrer überzeugen, die unsere Gruppe durchweg positiv bewerteten und sehen konnten, dass wir als Klasse viel Wissen aus den letzten beiden Schuljahren mitgenommen haben.

Als Fazit kann ich persönlich sagen, dass es auf jeden Fall eine tolle und konstruktive Erfahrung ist, einmal komplett eigenverantwortlich und mit eigener Zeiteinteilung eine solche Aufgabe zu bewältigen. Außerdem bringt dies die Schüler auch zwischenmenschlich und bzgl. der eigenen Persönlichkeit weiter, denn jeder lernt nicht nur die eigenen Stärken und die der Mitschüler kennen und schätzen, sondern muss auch mit Schwächen und Fehlschlägen zurechtkommen bzw. anderen aus diesen heraushelfen. Es ist eben doch ganz gut, wenn man ab und zu mal die eigene Komfortzone verlässt!

Wer sich nun angesprochen fühlt, auch mal in die IT-Welt zu schnuppern oder mit dem Gedanken spielt, eine Ausbildung im Bereich Informatik zu machen, dann schreibt uns doch einfach unter jobs@netways.de. Mehr Infos findet Ihr auch auf unserer Webseite oder in unserer Stellenausschreibung zum Azubi Fachinformatik. Mehr Informationen zum Thema Ausbildung Fachinformatiker findet Ihr auch auf der Webseite der IHK.

 

Bildquellen: 
https://www.unixmen.com/how-to-install-lamp-stack-ubuntu-17-04/
http://www.b3-fuerth.de/ 

Nicole Lang

Autor: Nicole Lang

Ihr Interesse für die IT kam bei Nicole in ihrer Zeit als Übersetzerin mit dem Fachgebiet Technik. Seit 2010 sammelt sie bereits Erfahrungen im Support und der Administration von Storagesystemen beim ZDF in Mainz. Ab September 2016 startete Sie Ihre Ausbildung zur Fachinformatikerin für Systemintegration bei NETWAYS, wo sie vor allem das Arbeiten mit Linux und freier Software reizt. In ihrer Freizeit überschüttet Sie Ihren Hund mit Liebe, kocht viel Gesundes, werkelt im Garten, liest Bücher und zockt auch mal gerne.

NodeJS HA mit PM2…

ich hatte in Vergangenheit bereits einen Blog Post über NodeJS in Verbindung mit dem NodeJS ‘Cluster’ Modul geschrieben ( siehe hier ), nun möchte ich euch zeigen wie Ihr eure NodeJS Anwendung auch ohne Programmierarbeit (also als reine Ops Tätigkeit) zum Cluster umfunktioniert und wie ihr diese anschließend verwalten könnt.

nodejs-logo-2015

Legen wir los, wir benötigen hierzu NodeJS, am besten 4.4 LTS und 4 zusätzliche Module/Helper, fangen wir also mit der Installation an…

$ npm install -g pm2
$ npm install -g express-generator
$ mkdir ~/project && cd project
$ npm install --save express
$ npm install --save sleep

…nun generieren wir das Express Anwendungsgerüst…

$ express -f .
 
   create : .
   create : ./package.json
   create : ./app.js
   create : ./public
   create : ./public/javascripts
   create : ./public/images
   create : ./public/stylesheets
   create : ./public/stylesheets/style.css
   create : ./routes
   create : ./routes/index.js
   create : ./routes/users.js
   create : ./views
   create : ./views/index.jade
   create : ./views/layout.jade
   create : ./views/error.jade
   create : ./bin
   create : ./bin/www
 
   install dependencies:
     $ cd . && npm install
 
   run the app:
     $ DEBUG=project:* npm start
 
$

… danach löschen wir in der Datei app.js alles von Zeile 13 bis 58, wir benötigen nur das Gerüst selbst und ein paar Zeile selbst geschriebenen Code, um diesen kommen wir leider nicht herum, da wir ja auch was sehen wollen.

Fügt nun ab Zeile 14 folgenden Code hinzu…

var crypto = require( 'crypto' );
var util = require( 'util' );
var sleep = require( 'sleep' ).sleep;
 
function getRandHash() {
    var current_date = (new Date()).valueOf().toString();
    var random = Math.random().toString();
    return crypto.createHash('sha1').update(current_date + random).digest('hex');
}
 
var myID = getRandHash();
 
app.get( '/', function( req, res ) {
    sleep( Math.floor( (Math.random() * 3) + 1 ) );
    res.send({
        "ID": myID,
        "PID": process.pid,
        "ENV": process.env
    });
});

…nun starten wir die App über PM2 im Cluster Mode, hier bitte dem Parameter ‘-i’ nur einen Wert gleich der Anzahl der CPU Cores mitgeben. Dann testen wir das Ganze doch gleich mal…

$ cd project
$ pm2 start bin/www -i 4

…ihr solltet nun folgende Ausgabe zu sehen bekommen…

pm2-start-www-cluster

…ihr könnt eure Anwendung auch auf Fehler überprüfen, dafür gibt euch PM2 einen Parameter ‘logs’ mit, der wiederum einige Flags kennt. Wenn ihr nur ‘pm2 logs’ eingebt dann bekommt ihr die Standardausgabe unserer Anwendung zu sehen, wenn ihr zusätzlich das Flag ‘–err’ mit angebt, bekommt ihr die Standard Fehlerausgabe, was für das Debugging recht hilfreich ist.

pm2-logs-examine

So, nun könnt ihr in eurem Browser mal die Anwendung aufrufen. Der Listener der Anwendung horcht auf dem Port 3000. Ein Aufruf auf http://127.0.0.1:3000 sollte ein JSON liefern, ähnlich zu dieser Ausgabe hier…

pm2-cluster-test1

Da wir in unserem Code eine künstliche Verzögerung eingebaut haben, könnt ihr nun mit 2 direkt Aufeinander folgenden Browser Reload sehen das sich die ID u. PID Werte gelegentlich ändern, dies bedeutet, dass unsere Cluster Anwendung funktioniert.

pm2-logo

Ich hoffe ich konnte euch nun zum Spielen und Experimentieren animieren. PM2 wird von der Firma Kissmetrics als OpenSource Project stetig weiter entwickelt und hat noch so viel mehr zu bieten, ganz findige unter euch werden die Monitoring API zu schätzen wissen und diese vmtl. in Icinga2, Graphite, Kibana und anderen Lösungen integrieren wollen.

Dann bis demnächst 🙂

Enrico Labedzki

Autor: Enrico Labedzki

Enrico ist beruflich ganz schön rumgekommen – IT hat ihn aber immer beschäftigt. Nach einem Ausflug in die Selbstständigkeit im Bereich Webentwicklung und Network Solutions, wurde es dann Zeit Nägel mit Köpfen zu machen und endlich den Weg als Softwareentwickler und Systemintegrator einzuschlagen. In seiner Freizeit widmet sich der passionierte Bastler der Elektrotechnik und Animatronik. Bei Netways bereichert er mit seinem vielseitigen Know-How das Managed Service-Team.

JavaScript Data-Watchpoints

Jeder der eine größere Anwendung debuggt, wird sich schnell in einer Situation wiederfinden, in der einfache Breakpoints nicht mehr ausreichen um die Ursache des Fehlers zu finden. Die meisten modernen Debugger beherrschen deswegen das Setzen von Watchpoints.

Watchpoints beobachten eine Variable und halten die Ausführung des Programmes an, sobald sich der Wert der Variable ändert. Auch wenn die Entwicklertools der meisten Browser ziemlich fortgeschritten sind, sucht man Watchpoints hier jedoch vergeblich. Glücklicherweise gibt es ein paar Möglichkeiten um dieses Dilemma herumzuarbeiten, indem man die Watchpoints direkt in JavaScript oder der Konsole setzt:

Gecko-basierte Browser wie Firefox bieten die Möglichkeit die Watchpoints mit der Funktion Object.prototype.watch() direkt in der Debugging-Konsole zu setzen.

var someVar = { myProperty: 'foo' };
Object.watch('myProperty', function () { 
   console.log('myProperty changed!');
});

Chrome besitzt das noch mächtigere Object.observe(), mit dem man beliebige Variablen beobachten kann und nicht nur Member von Objekten.

var someVar = ...
Object.observe(someVar, function () { 
   console.log('someVar changed!');
});

Für alle anderen Browser gibt es einen Polyfill, der den Objekt-Prototyp mit einer neuen Funktion .watch() erweitert.

Als i-Tüpfelchen kann man nun noch den Debugger halten lassen sobald der gesetzte Watchpoint ausgeführt wird. Hierfür verwendet man im Callback das Statement debugger; welches in nahezu allen Browsern funktioniert.

Object.observe(someVar, function (name, object, type, oldValue) {
    debugger;
});
Matthias Jentsch

Autor: Matthias Jentsch

Aktuell studiert Matthias Informatik an der Ohm und arbeitet als Werkstudent bei uns. Seinen hohen Kaffeeverbrauch kompensiert er mit Javascript und NodeJS und erstellt für uns interne Tools zur Ressourcenverwaltung.