Server-Probleme im Zeitalter von HTTP/2

Ich hatte heute das Problem, dass einige Webseiten extrem langsam bis gar nicht mehr vom Webserver ausgeliefert wurden. Also prüfe ich als erstes mit “htop” ob die CPU ausgelastet ist, danach via “iotop” die Festplatte, mit “iftop” den Traffic, mit “netstat” die offenen Netzwerkverbindungen und via “free” wie viel Speicher noch zur Verfügung steht. Und die Hardware war nicht mal ansatzweise ausgelastet. Nach einigen weitere Tests ist schnell aufgefallen, dass nur “http”-Anfragen betroffen waren. Selbst eine einfach GET-Anfrage eines Bildes ist zeitweise fehlgeschlagen.

Die größte Änderung am Vortag war, dass eine Webseite mit zirka 1 Millionen Usern komplett auf “https://” umgestellt wurde. Daher habe ich kurzfristig wieder auf “http://” umgestellt, jedoch ohne eine Änderung festzustellen.

linux_kill_9
Quelle: http://www.reddit.com/r/ProgrammerHumor/comments/27vcjg/signal_kill/

Zeitgleich ist aufgefallen das der MySQL-Prozess nicht korrekt neugestartet ist, somit liefen zwei MySQL-Server (ps aux | grep mysql), wobei nur einer wirklich Anfragen angenommen hat. Der zweite Prozess wollte sich nicht mehr via “service mysql restart” neustarten lassen, hat die Fehlermeldung “Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysql.sock’” produziert und wurde daher via “kill” getötet und anschließend der MySQL-Server neugestartet.

Dies hat auch das Problem mit den langsamen Webseiten behoben, zumindest kurzweilig. Danach hatten “http”-Anfragen wieder Probleme. Im “error”-Logfile (/var/log/apache2/error.log) vom Apache habe ich dann endlich eine Meldung gefunden, welche mich auf die richtige Fährte gebracht hat: “server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers settings”

website-download-with-spdy

Vor einer Woche hatte ich das “SPDY“-Protokoll auf dem Server aktiviert und getestet, alles hat ohne Probleme funktioniert. Dann habe ich gestern die bereits erwähnte Webseite komplett auf “https” umgeroutet und noch immer kein Problem festgestellt. Am Morgen wurden dann Newsletter versendet und eine ganze Menge Leute sind in kurzer Zeit via “https” auf die Webseite gekommen, da das “SPDY”-Protokoll nur mit “https” arbeite haben diese User nicht die üblichen Anfragen  (HTTP 1.0 / 1.1) an den Server gestellt, sondern durch Multiplexverfahren mehrere Anfragen gleichzeitig verarbeitet werden.

http-diagram-spdy
Quelle: http://stackoverflow.com/questions/10480122/difference-between-http-pipeling-and-http-multiplexing-with-spdy

Die erste Intuition, dass es etwas mit der “SSL”-Umstellung zu tun hatte war schon mal nicht verkehrt, jedoch hatte ich die entsprechenden Einstellungen nur in der “.htaccess” auskommentiert, die “https”-Verbindungen jedoch nicht zurück nach “http” umgeleitet …

RewriteCond %{SERVER_PORT} !^443
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

… und den Apache nicht neugestartet, somit waren die aktuellen Anfragen noch aktiv und Nutzer welche auf der Webseite waren haben weiter “https”-Anfragen generiert.

Im nächsten Schritt musste nun festgestellt werden, wie viele Apache Prozesse bzw. gleichzeitige Verbindungen einstellt werden mussten und wie man dies am besten konfiguriert. Die Apache-Dokumentation sagt hierzu folgendes:

“The MaxRequestWorkers directive sets the limit on the number of simultaneous requests that will be served … For non-threaded servers (i.e., prefork), MaxRequestWorkers translates into the maximum number of child processes that will be launched to serve requests. The default value is 256; to increase it, you must also raise ServerLimit.”

Also habe ich via …

netstat -anp | grep -E ":80|:443" | grep ESTABLISHED | wc -l

… bzw. zur groben Orientierung via …

ps aux | grep apache | wc -l

… herausgefunden wie viele http(s) Anfragen bzw. Apache Prozesse aktuell vorhanden sind und habe diese Einstellungen zunächst entsprechend hoch eingestellt (“/etc/apache2/mods-enabled/mpm_prefork.conf”), so dass die Webseite wieder korrekt funktionierte. Anschließend habe ich die zuvor beschriebenen Befehle verwendet, um die endgültigen Einstellungen zu ermitteln. Die folgenden Einstellungen sind an einen Server mit 32G Arbeitsspeicher getestet und sollte nicht einfach übernommen werden.

<IfModule mpm_prefork_module>
ServerLimit                                    1024
StartServers                                        1
MinSpareServers                              32
MaxSpareServers                          250
MaxRequestWorkers              1024
MaxConnectionsPerChild             0
</IfModule>

————————————————–

Lösung: Wenn man das “SPDY”-Modul aktiviert und später auf “SSL” umstellt, sollten man vorher die Apache-Konfiguration anpassen! ;)

————————————————–

Es folgt noch ein kleines Tutorial, wie man “SPDY” für Apache installieren kann. Jeder der bereits auf “nginx” umgestiegen ist, kann dies ggf. bereits ohne weitere Installation ausprobieren: http://ginx.org/en/docs/http/ngx_http_spdy_module.html

Installation: SPDY für Apache 2.2

Download: https://developers.google.com/speed/spdy/mod_spdy/

# z.B.: wget https://dl-ssl.google.com/dl/linux/direct/mod-spdy-beta_current_amd64.deb
dpkg -i mod-spdy-*.deb
apt-get -f install

Installation: spdy für Apache 2.4

apt-get -y install git g++ apache2 libapr1-dev libaprutil1-dev patch binutils make devscripts fakeroot
cd /usr/src/
git clone https://github.com/eousphoros/mod-spdy.git
## wähle deine Apache Version  
# z.B.: git checkout apache-2.4.7
# z.B.: git checkout apache-2.4.10
cd mod-spdy/src
./build_modssl_with_npn.sh
chmod +x ./build/gyp_chromium
rm -f out/Release/mod-spdy-beta*.deb
BUILDTYPE=Release make linux_package_deb
dpkg-i out/Release/mod-spdy-beta*.deb

Video:

Links:

– Projekt Webseite: http://www.chromium.org/spdy/

– Quellcode: https://code.google.com/p/mod-spdy/wiki/GettingStarted

– “mod_spdy” für Apache 2.2: https://developers.google.com/speed/spdy/mod_spdy/

– “mod_spdy” für Apache 2.4: https://github.com/eousphoros/mod-spdy

– Online-Test für “SPDY”: https://spdycheck.org/

– Präsentation zum Thema “HTTP/2” von @derschepphttps://schepp.github.io/HTTP-2/

– Browserkompatibilität mit “SPDY”: http://caniuse.com/#search=spdy

I ❤ ~/

Vor einiger Zeit habe ich bereits einen Blog-Post über meine “.dotfiles” geschrieben, jedoch habe ich mich damals mehr auf die Installation beschränkt und habe keine Beispiele gezeigt, so dass man den Vorteil der .dotfiles nur schwer erfassen konnte.

Außerdem benötigt man ggf. nur einige Funktionen oder Dateien um sein System an an seine Bedürfnisse anzupassen. Auf der Webseite GitHub ❤ ~/ gibt es sehr gute .dotfiles Sammlungen, welche man einfach “forken” und anpassen und nutzen kann.

PS: wer sich bisher nicht mit “git” auskennt, sollte sich einmal eines der folgenden interaktiven git-Tutorials anschauen:
try.github.io/
pcottle.github.io/learnGitBranching/
gitreal.codeschool.com/


Beispiele zu meinen .dotfiles:

Navigation:
https://github.com/voku/dotfiles/blob/master/.aliases#L75 easier navigation via aliases

Farben für die Kommandozeile:
https://github.com/voku/dotfiles/blob/master/.aliases#L116color for ping / traceroute / ps / top / ...

difflight & filename auto-completion via zsh

Nützliche Shortcuts: z.B. date_*
https://github.com/voku/dotfiles/blob/master/.aliases#L295
more useful shortcuts

Copy&Past via “getclip” und “putclip”: https://github.com/voku/dotfiles/blob/master/.aliases#L368copy text via "getclip" & putclip

kill & pkill via z-shell: https://github.com/voku/dotfiles/blob/master/.redpill/lib/4_completion.zsh#L122kill & pkill via z-shell

grep & ack: https://github.com/voku/dotfiles/blob/master/.aliases#L242grep & ack

git via z-shell: https://github.com/voku/dotfiles/blob/master/.gitconfiggit via z-shell

“ls”-aliases: https://github.com/voku/dotfiles/blob/master/.aliases#L196optimized "ls"-aliases

vim » Automatisch zur letzten Position springen 
https://github.com/voku/dotfiles/blob/master/.vimrc "vim" » jump to last position

vim » Schell-Suche via “#” "vim" » quick search via "<#>" or "*"

vim » markieren Leerzeichen am Ende der Zeile"vim" » highlight trailing spaces in annoying red

vim » Tabs nutzen
https://github.com/voku/dotfiles/blob/master/.vimrc#L564
vim » NERD Tree via “,” + “-“
https://github.com/voku/dotfiles/blob/master/.vimrc.bundles#L18"vim" » "tabs" & "file-view"

vim » Autovervollständigung via Tabulatur-Taste
https://github.com/voku/dotfiles/blob/master/.vimrc#L755"vim" » tab-completion


Erklärungen zu meinen .dotfiles:

.config_dotfiles

In dieser Datei kann man Einstellungen für meine .dotfiles vornehmen. Wenn du z.B. deinen Standard-User-Namen in der Variable “CONFIG_DEFAULT_USER” hinterlegst, wird diese nicht mehr in der Shell-Prompt angezeigt.

.path

In dieser Datei kannst du Pfade zu deinen Ausführbaren Dateien einfügen, so dass du diese ohne Angabe des Pfades ausführen kannst.

Diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. z.B.: export PATH=”$HOME/utils:$PATH”

.load

In dieser Datei laden wir weitere optionale Einstellungen, welche ggf. gar nicht installiert und somit auch nicht geladen werden müssen.

.colors

Hier definieren wir einige Farben, welche dann in den folgenden Dateien verwendet werden können. z.B.: COLOR_BLACK=\e[0;30m

.exports

Variablen in Shell-Scriptes verhalten sich so ähnlich wie in JavaScript. Variablen sind Standardmäßig “global”, dass heißt selbst Variable innerhalb einer Funktion sind anschließend auch außerhalb der Funktion verfügbar. Daher verwenden wir “local” innerhalb von Funktionen, für Variablen welche nur innerhalb der Funktion zur Verfügung steht sollen. Außerdem können wir Variablen via “export” exportieren, so dass diese nicht nur zur Ausführungszeit, sondern anschließend ebenfalls allen Kindprozessen als Umgebungsvariable zur Verfügung stehen.

.icons

Wie die Farben werden auch die entsprechenden Icons exportiert, so dass wir diese anschließend in Funktionen etc. nutzen können.

.aliases

In dieser Datei werden Abkürzungen für komplexe Befehle oder / und Fallbacks definiert, welche anschließend als Befehl ausgeführt werden.

z.B.:
alias starwars=’telnet towel.blinkenlights.nl’
alias sgrep=’grep -R -n -H -C 5 –exclude-dir={.git,.svn,CVS}’

.bash_complete // completion.zsh

Auch wenn die “Z-Shell” (zsh) bessere Tabcompletion bietet, kann man auch in der “Bash” einige  Tabcompletion-Features nutzen.

z.B.:

apt- [Tabulator]
apt-g [Tabulator]
apt-get [Tabulator]
apt-get i [Tabulator]
apt-get install [Tabulator] [Tabulator]
apt-get install apa [Tabulator]

.functions

Hier habe ich einige praktische Funktionen gesammelt, welche ich öfters nutze und nicht als Plugin auslagern möchte.

z.B.:
lman() -> “Open the manual page for the last command you executed”
netstat_free_local_port() -> “get one free tcp-port”
iptablesBlockIP() -> “block a IP via ‘iptables'”

Überlegungen: In der “normalen” Programmierung nutzt man lowerCamelCase für normale Variablen / Funktionen und Methoden, jedoch sind eigentlich alle Funktionen in der Shell lowercase z.B.: whoami, updatedb, killall. Ich mich dafür entschieden mich bei neuen Funktionen und Aliases an einem Original-Befehl zu orientieren, so dass man diese nicht neu lernen muss, sondern diese via [Tabulator] nutzen kann.

.extra

Auch diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. Hier kann man alle zuvor gesetzten Variablen, Einstellungen, Funktionen überschreiben oder ergänzen.

“gzip” für Webseiten

Um das Verhalten von “gzip / deflate” besser zu verstehen, möchte ich als erstes ganz kurz auf den Algorithmus hinter der Komprimierung eingehen. Dafür muss man zumindest zwei Grundlegende Theorien verstehen. Zum einen die sogenannte Huffman-Kodierung, dabei geht darum Text mit möglichst wenig Bits (0 || 1) zu übersetzen.

Es folgt ein einfaches Beispiel:

String: “im westen nichts neues”

Die Länge des Strings beträgt 22 Zeichen, was bei einem 4-Bit-Code (0000, 0001 …) eine Anzahl von 22 * 4 Bit = 88 Bit ergeben würde.

Berücksichtigt man jedoch die Häufigkeit der wiederkehrenden Zeichen, kann man für bestimmte Zeichen, welche oft im String vorkommen, kürzere Bit-Codes nutzen.

huff1

Als erstes Zählen wir die Anzahl der vorkommenden Zeichen. Die Zeichen welche die geringste Häufigkeit aufweisen werden anschließend als erstes miteinander Verknüpft und jeweils addiert.

huff4

Wie man bereits erkennt bekommen die Zeichen welche nicht so häufig auftreten längere Strecken und somit gleich auch längere Bit-Codes.

huff7

Wenn man alle Zweige verknüpft hat, entsteht daraus dann ein Binär-Baum, welcher von oben nach unten gelesen wird.

Die eindeutigen Bit-Codes sind nun z.B.: 00 für e, 100 für n, 1011 für t und so weiter. Nun benötigen wir nur noch 73 Bit anstatt 88 Bit, um den String binär darzustellen. ;)

Das zweite Prinzip hat auch mit Wiederholung von Zeichen zu tun. Die sogenannte “LZ77″ Kompression, welche wiederkehrende Muster in Strings erkennt und durch Referenzen von vorherigen Strings ersetzt.

Es Folgt ein einfaches Beispiel:

String: “Blah blah blah blah blah!”

 vvvvv     vvvvv     vvv
Blah blah blah blah blah!
      ^^^^^     ^^^^^

Wenn man nun die Wiederholung durch eine Referenz angibt, welche aus der Länge des Wortes (” blah” = 5) und Länge der Wiederholungen. (“lah blah blah blah” = 18). Daraus ergibt sich anschließend der folgende komprimierte Text.

Blah b(5,18)!

… aber nun endlich zum praktischen Teil! Es folgen ein paar Beispiele und Überlegungen im Zusammenhang mit Webseiten / Webservern.

1.) “gzip”, ABER weniger ist manchmal mehr

Bei kleinen Webseiten und schwachen V-Servern kann es vorkommen, dass die serverseitige Komprimierung im Gesamtkontext keinen Geschwindigkeitsvorteil bietet, da die Komprimierung ggf. mehr Overhead (Payload, CPU-Rechenzeit, Verzögerung der Auslieferung) mit sich bringt als es Vorteile (geringere Dateigröße) bietet. Zumal viele Dateien (Bilder, CSS, JS) nach dem ersten Seitenaufruf im Cache sind und nicht wieder vom Server ausgeliefert werden müssen. Gerade für mobile Geräte macht die Komprimierung jedoch fast immer Sinn, daher würde ich die Komprimierung immer aktivieren!

PS: hier noch ein Blog-Post zum Thema Webseiten Beschleunigen

moelleken_org-gzip
mit gzip
moelleken_org-nogzip
ohne gzip

GRÜN = Download
GELB = Wartet
BLAU = Verbindung zum / vom Server

Bei “nginx” gibt es zudem ein Modul (HttpGzipStaticModule) welches direkt vorkomprimierte Dateien ausliefert, anstatt diese bei Anfrage zu komprimieren. Jedoch muss man bisher selber dafür sorgen, dass eine entsprechende Datei mit dem selben Timestamp vorhanden ist. (z.B.: main.css & main.css.gz) Falls jemand hier eine Alternative oder ein einfaches Script zum erstellen der zu komprimierenden Dateien hat, meldet euch bitte bei mir oder einfach in den Kommentaren.

2.) “gzip”, ABER nicht für alles

Zunächst sollte man bereits komprimierte Dateien (z.B. JPEG, PNG, zip etc.) nicht noch zusätzlich via „gzip“ ausliefern, da die Dateigröße im schlimmsten Fall noch steigen kann oder zumindest wird für sehr wenig Dateigröße, sehr viel CPU-Zeit auf der Server (Komprimierung) und auf dem Client (Dekomprimierung) verbraucht.

gzip_images

Ich empfehle an dieser Stelle mal wieder die “.htaccess“-Datei vom HTML5-Boilerplate, welche bereits viele Einstellungen für den Apache-Webserver liefert. Außerdem gibt es dort auch eine optimierte Konfiguration “nginx.conf” für den nginx-Webserver.

3.) “gzip”, ABER nicht immer

Die “gzip”-Komprimierung kann Ihre Stärken bei größeren Dateien viel besser ausspielen, da wir ja bereits im theoretischen Teil gelernt haben, dass die Komprimierung auf Wiederholungen aufbaut und wenn wenig wiederkehrende Zeichen und Muster vorhanden sind lässt es sich schlecht komprimieren.

Beim “nginx”-Webserver kann man die minimale zu bearbeitende Dateigröße angeben, sodass eine 6 Byte große Datei mit dem Inhalt “foobar” bei schwacher „gzip“ nicht auf 40 Byte vergrößert wird.

gzip_small_file

4.) “gzip”, ABER nicht so hoch

Zudem sollte man nicht mit der höchsten Komprimierungsstufe komprimieren, da man pro Komprimierungsstufe immer weniger Erfolg bei immer mehr CPU-Zeit bekommt. Man sollte weniger stark komprimieren und dadurch Rechenleistung /-zeit einsparen, um die Webseite schneller ausliefern zu können.

gzip_level

test2_1.js.gz (schwache Komprimierung)
test2_2.js.gz (normale Komprimierung)
test2_3.js.gz (starke Komprimierung)

5.) „gzip“ + Minifizierung

Durch Minifizierung von CSS und JS kann man die Dateigröße ebenfalls reduzieren, auch wenn man nicht an die Dateigröße von komprimierten Dateien herankommt, außerdem sinkt der Erfolg der Komprimierung, da wir durch die Minifizierung bereits einige Wiederholungen minimiert haben.

Es folgt ein Beispiel mit „jquery.js / jquery.min.js“:

Zustand

Größe der Datei

gewonnene Größe durch die Komprimierung

nicht minifiziert + nicht komprimiert Datei

250 kB (¼ MB)

nicht minifiziert + schnelle Komprimierung

76,3 kB

173,7 kB

nicht minifiziert + normale Komprimierung

68,3 kB

181,7 kB

nicht minifiziert + hohe Komprimierung

68 kB

182 kB

minifiziert + nicht komprimiert Datei

82,3 kB

minifiziert + schnelle Komprimierung

30,8 kB

51,5 kB

6.) “gzip” + Komprimierung verbessern

Im Gegensatz zur Programmierung, wo man Wiederholungen vermeidet, sollte man im Frontend (HTML, CSS) gezielt Wiederholungen nutzen, um die Komprimierung zu optimieren. So zeigt  das folgende Beispiel wie man die Dateigröße durch die korrekte Positionierung von Attributen der HTML-Tags verbessern kann.

Zwei Dateien mit dem selben Dateigröße, nur die Reihenfolge der Attribute in der zweiten HTML-Dateien (“test1_2.html”) wurden nicht in der selben Reihenfolge angegeben.

html_order_3
test1_1.html
html_order_2
test1_2.html

html_order

Wie man in dem Bild erkennen kann, haben wir die Dateigröße der HTML-Datei um zirka 10% reduziert indem wir den Komprimierungsalgorithmus  bei der Arbeit unterstützen. ;)

Videos:

 

DO EPIC SHIT!

Slides | Demo (source)

Auf der OpenRheinRuhr (Messe mit Kongress rund um das Thema “Freie Software”) habe ich meinen ersten öffentlichen Vortrag gehalten. Dazu habe ich das Thema “Open Source Workflow für Webentwickler” gewählt und mit dem doch sehr einprägsamen Titel “DO EPIC SHIT!” angekündigt.

B16GnDZIcAA3aRb

Gegen alle Erwartungen bin ich pünklich angekommen, auch wenn die Bahn (GDL) gestreikt hat. Also hatte ich noch etwas Zeit, um noch einen `git commit` vorzubereiten, welcher dann live in dem Vortrag automatisch via Jenkins getestet und deployed werden konnte.

Und auch wenn ich den Vortrag nicht so beenden konnte wie ursprünglich geplant, da ich die Zeit irgendwie falsch eingeteilt hatte, hoffe ich trotzdem einiges nützliches gezeigt zu haben. Beim nächsten mal sollte ich dies wohl vor “echtem” Publikum testen, da die Zeit dann anscheinend anders verläuft. ;) Einige Erklärungen und Beispiele von der Demo-Webseite musste ich daher unterschlagen und reiche diese Infos im folgenden nach:

Backend:

Frontend:

Extras:

PS: Ich werde heute wieder auf der OpenRheinRuhr sein, da auch das heutige Programm sehr interessante Vorträge und Workshops biete. z.B.: DockerSaltStackImageMagick. Gegebenenfalls sieht man sich dort :) wünsche allen Beteiligten viel Spaß!

ShellShock – Sicherheitsproblem bei der Unix-Shell $(bash)

Alle alten Version der Unix-Shell “bash” enthalten eine kritische Sicherheitslücke (CVE-2014-6271), so dass man Befehle z.B. über CGI-Skripte oder via DHCP ausführen kann.  Ggf. benötigt nun dein Handy (z.B. CyanogenMod), dein Router oder deinen Mac / Linux / BSD und so weiter Software-Updates.

Teste dein System:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

vulnerable
this is a test

Nachdem man die aktuellen Updates eingespielt hat (z.B. via aptitude) dann sollte die Ausgabe folgendermaßen aussehen.

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

bash: warning: x: ignoring function definition attempt bash: error importing function definition for `x’ this is a test

Technische Erklärung:

(http://seclists.org/oss-sec/2014/q3/650)
Das Problem ist, dass das man zwischen unterschiedlichen Bash-Instanzen Variablen und Funktionen teilen kann.

export foo='() { echo "bar" ; }'
bash -c 'foo'

Jede neue Bash-Instanz wird nun beim Start die Funktion “foo”  registrieren, so dass man diese Ausführen kann. Wenn man nun jedoch eine Funktion exportiert, führt die Bash den nächsten Befehl ebenfalls aus, da der String der “() {” nicht korrekt geparst wird. Damit können wir nun Befehle ausführen, indem wir bestimmte Strings (Funktionsdefinitionen) an z.B. ein CGI-Skript übergeben.

Links:

http://www.heise.de/newsticker/meldung/Bash-Luecke-ShellShock-ist-noch-nicht-ausgestanden-2403607.html

http://www.heise.de/newsticker/meldung/ShellShock-Standard-Unix-Shell-Bash-erlaubt-das-Ausfuehren-von-Schadcode-2403305.html

http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-025

 

Projekte organisieren mit Trello.com

Heute möchte ich ein Web-Tool zur Organisation von Projekten vorstellen: https://trello.com

Trello nutzt “Listen”, welche sich auf sogenannten “Boards” befinden, um verschiedene Kategorien in einem Projekt abzubilden. Diese Listen beinhalten “Cards”, welche wiederum verschiedene Elemente (Checklisten, Bilder, E-Mails, Kommentare, etc.) enthalten können. Dabei empfehle ich das Tool einfach mal auszuprobieren, bevor man sich diesen und weitere Texte durchliest.

Live-Beispiel:  suckup.de

https://trello.com/b/SgOH9gbE/it-blog-suckup-de

Als Live-Beispiel möchte ich meinen Blog nutzen. Ich versuche meine Blog-Posts nun via Trello & Google-Docs zu organisieren. Dazu habe ich einige Kategorien (Blog-Ideen, Blog-Query, Blog-Artikel und Done) angelegt und bereits einige Themen-Vorschläge eingefügt.

trello

Weitere Überlegungen

Momentan überlege ich, wie man dieses grandiose Tool auch in der täglichen Arbeit einsetzten kann. Dazu würde ich zunächst (ganz noch Projektgröße) verschiedene Trello-Boards anlegen. Dabei kann man “Boards” auch in bestimmten “Organisations” anlegen, was ggf. eine bessere Übersichtlichkeit liefert.

Unbenannt-4

z.B. einige fiktive Organisation für meine private Webseite: http://moelleken.org

– “Planung”
– “Development”
– “Bugs”
– (“Refactoring”)
– (“Roadmap”)

Unbenannt-2

Dabei können die verschiedenen Tasks zur nächsten Projektphase weitergereicht werden.

Planung: erste Ideen
Trello_planung

Planung: konkrete Beschreibungen und Vorstellungen (hier sollten nach externe Dokumente / Bilder etc zur Beschreibung beigefügt werden)
Trello_planung2

Development: Bugs, Refactoring-Maßnahmen und neue Features können z.B. in einem Team Meeting in diese Kategorie verschoben und Priorisiert werden.
Trello_dev

Development: jeder im Team kann sehen, wer welches Feature, Bug etc. bearbeitet (dies Übersicht kann man mit farblichen “Labels” noch verbessern)
Trello_dev2

Am Ende der Woche kann man ein Fazit ziehen und ggf. im Team vorstellen, welche Tasks umgesetzt wurden, dies förder die Motivation, bringt Strukturen in das Projekt und verteilt das Wissen nebenbei noch auf verschiedene Mitarbeitet.

Fazit

Noch kann ich nicht sagen, ob diese Überlegungen auch im täglichen “Doing” einsetzbar oder von Vorteil sind. Daher folgt in den nächsten Tagen / Wochen ein weitere Blog-Post, welcher soeben unter “https://trello.com/b/SgOH9gbE/it-blog-suckup-de” geplant wird. ;)

Links

Trello: Projektmanagement leicht gemacht
Productivity-Tools: Projekte organisieren mit Trello.com

Spriting mit Compass

Allgemein

Ich gehe ganz kurz auf die Basics ein: Spriting ist eine Technik, welche viele kleine Bilder zu einem großem Bild zusammenfasst. Diese Technik spart nicht nur ein paar KB bei der Dateigröße, sondern hat den Vorteil, dass nicht zu viele Verbindungen zum Server aufgebaut werden müssen.

PS: Ich habe darüber bereits vor einiges Zeit im Zusammenhang mit “Webseiten Komprimierung” geschrieben.

Kommen wir jetzt jedoch zum interessanten Teil. Wie setzt man dies ein, ohne bei jeder kleinen Bildveränderung / Hinzufügung Mehraufwand zu generieren.  Und die Lösung heißt “compass“. Dies ist ein Framework, welches auf Sass aufsetzt und dieses um einige nützliche Features ergänzt.

Installation / Konfiguration

Hier ist ein kleines Bash-Skript, welches in meinen “.dotfiles” beinhaltet ist und die erforderlichen Programme (ruby, sass, compass, oily_png) installiert.

github.com/voku/dotfiles/blob/master/firstInstall.sh

Es folgt eine Beispiel-Konfiguration für compass, woraus sich bereits die Order für Bilder, Scss, css und js hervorgehen:

github.com/voku/twig-wrapper-example/blob/master/config.rb

 

Beispiel

icons icons_new

URL: moelleken.org/tpl_imageSprites.php

SCSS:

Ich habe die für das Sprite relevanten Zeilen rot gekennzeichnet. Außerdem sollte man erwähnen, dass der Verzeichnis-Name “**/spritesTest/” sich in der “include”-Anweisung wiederfinden muss. Die Bilder selber lassen sich anschließend über den Dateinamen im CSS referenzieren, so dass man möglichst einfache / eindeutige Dateinamen verwenden sollte.

PS: hier findet du das entsprechende CSS, welches diese paar Zeilen SCSS generieren

// compass
@import "compass/css3";
@import "compass/utilities/sprites";

/*
 *  - - - - - - - - - -
 * some icons for testing
 *  - - - - - - - - - -
 */

@import "../images/spritesTest/*.png";
@include all-spritesTest-sprites;
#spritesOverview span {
  width: 32px;
  height: 32px;
  display: block;
  transition: all 0.2s ease-in;
  &:hover {
    @include transform(scale(1.8));
    transition: all 0.4s ease-out;
  }
}

@for $i from 1 through 20 {
  .step#{$i} {
    animation: movement 1500ms ease (75ms * $i) infinite alternate;
  }
}

@keyframes movement {
  from {
    @include transform(scale(1.0) translateY(0px) rotateX(0deg));
    box-shadow: 0 0 0 rgba(0,0,0,0);
  }
  to {
    @include transform(scale(1.5) translateY(-25px) rotateX(45deg));
    box-shadow: 0 25px 25px rgba(0,0,0,0.2);
  }
}

 

PHP:

Die paar Zeilen PHP habe ich nur hinzugefügt, da ich keine Lust hatte alle Dateinamen in ein großes Array zu kopieren und diese Datei direkte von der Festplatte auslese.

<?php
use cms\Path;
use cms\twig\TwigWrapper;

require_once 'inc_globals.php';

$fileArray = file_list(Path::getPathDirTheme() . '/images/spritesTest', 'png');

$icons = array();
foreach ($fileArray as $file) {
  $file = str_replace(Path::getPathDirTheme() . '/images/spritesTest/', '', $file);
  $file = str_replace('emblem-', '', $file);
  $file = str_replace('.png', '', $file);

  $icons[] = $file;
}

// DEBUG
//dump($icons);
// #############################################################################
// # TwigWrapper | templating
// #############################################################################
$twigWrapper = new TwigWrapper('tpl_imageSprites.twig');

$iconsArray = array();
for ($i = 1 ; $i <= 20 ; $i++) {
  shuffle($icons);
  $iconsArray[] = $icons;
}

$twigWrapper->assign('iconsArray', $iconsArray);

echo $twigWrapper->render();

 

Twig:

Zum Schluss noch ein paar HTML-Tags im Twig hinzugefügt und schon können wir die Icons bewundern. ;)

{% extends "tpl_base.twig" %}

{% block head_css %}
  {{ parent() }}
  <link rel="stylesheet" href="{{ urlTheme }}/css-min/sprites.css" />
{% endblock %}

{% block content %}
  {{ breadcrumb | raw }}

  <article id="spritesOverview">

    {% for i in 1..20 %}

      <div class="row step{{ loop.index }}">
        {% for icon in iconsArray[i] %}
          {% if loop.index <= 6 %}
            <div class="medium-2 columns"><span class="spritesTest-emblem-{{ icon }}"></span></div>
          {% endif %}
        {% endfor %}
      </div>

    {% endfor %}

  </article>
{% endblock %}

 

Links:

compass-style.org/reference/compass/helpers/sprites/
Compass Tutorials #6 – Sprites In Compass

V-Server Problem bei Strato

Mein Virtueller Server von Strato hat diese Woche erhebliche Probleme. Angefangen hat dies bereites letzte Woche, daher habe ich am 22.06.2014 eine Support-Anfrage mit der Bitte um Prüfung geschrieben, jedoch bisher nur die Antwort erhalten, dass ein überlastetet Hostsystem ggf. zu den Problemen führt und dass dies momentan geprüft wird.

– Server-“Load”: > 10
– CPU-Auslastung : ~ 0%
– I/O-Auslastung: ~ 0%

——————————————

Reaktionszeit: 1/2 Min. für den SSH-Login  :-(

Daher kann es zwischenzeitlich auf dieser Webseite noch zu erheblichen Ladezeiten kommen, ich bitte dies zu entschuldigen. Wenn jemand einen guten Tipp für einen neuen Hoster hat oder andere Schlüsse aus den folgenden Screenshots ziehen kann, schreibt mir dies bitte per E-Mail “lars (at) moelleken.org” oder einfach direkt hier als Kommentar, vielen dank! Mfg Lars

 

server_vmstat

server_iotop

server_top

 

Falls jemand ebenfalls Performance-Probleme mit seinem Linux-Server hat, sollte man sich einmal folgenden aktualisierten Blog-Post anschauen:

-> Server-Analyse: http://suckup.de/linux/linux-server-analysieren/

 

UPDATE: 02.07.2014 15:59

Sehr geehrter Herr Moelleken,

ich möchte Sie mit dieser E-Mail über den Bearbeitungsstand Ihres Troubleticket informieren.

Sie hatten von Beeinträchtigungen bezüglich der Performance Ihres STRATO Virtual Server Linux berichtet.
Vorab bitte ich die Ihnen dadurch entstandenen Unannehmlichkeiten zu entschuldigen.

Erfreulicherweise kann ich Ihnen nun mitteilen, dass die Einschränkungen an Ihrem Server mittlerweile vollständig behoben wurden. Ihr Server ist damit wieder in vollständigem Umfang und mit gewohnter Performance zu erreichen.

Ich wünsche Ihnen weiterhin viel Erfolg mit Ihrem STRATO Server und stehe auch weiterhin bei Rückfragen für Sie bereit.

 

Multi-Platform Mobile Apps via Ionic

Ionic ist ein Frontend-Framework, mit welchem man via HTML5 / JavaScript und CSS native Apps bauen kann. Diese Apps können via “Apache Cordova” auf native Funktionen (Kamera, GPS, etc.) der Geräte zugreifen. Zudem wird Google’s JavaScript Framework “AnguarJS” genutzt und natürlich wird auch “SASS” unterstützt.

Vorbereitung

Man kann Multi-Platform Mobile Apps sowohl unter Windows, Linux oder Mac OS X entwickeln, jedoch ist die Vorbereitung unter Linux / Mac OS X um einiges einfacher.

Ich empfehle an dieser Stelle mal wieder die “.dotfiles” zu installieren.

cd ~ 
git clone https://github.com/voku/dotfiles.git 
cd dotfiles 
source bootstrap.sh

# Standard- & Webworker-Tools installieren

~/dotfiles/firstInstall.sh

Bei der Frage nach den “webworker tools”,  muss diese mit “y” beantwortet werden.

# Android SDK installieren

sudo ~/dotfiles/android_sdk_install.sh

# Java installieren

sudo add-apt-repository -y ppa:webupd8team/java
sudo aptitude update
sudo aptitude install oracle-java7-installer

# Ant installieren

sudo apt-get install ant

 

Nachdem die Installation komplett abgeschlossen ist, muss die “~/.extra”-Datei angepasst werden.

z.B.:

#!/bin/bash                                                                                                                                                                                                       

DEFAULT_USER="lars"
GIT_AUTHOR_NAME="Lars Moelleken"
GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
git config --global user.name "$GIT_AUTHOR_NAME"
GIT_AUTHOR_EMAIL="lars@moelleken.org"
GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
git config --global user.email "$GIT_AUTHOR_EMAIL"
git config --global push.default simple

# java - example
export JAVA_HOME=/usr/lib/jvm/java-7-oracle
export JDK_HOME=$JAVA_HOME
export JRE_HOME=$JAVA_HOME
export PATH=$JAVA_HOME/bin:$PATH

# android - example
export ANDROID_SDK_ROOT=/usr/local/android-sdk/
#export ANDROID_NDK=/usr/local/android-ndk/
export ANDROID_HOME=$ANDROID_SDK_ROOT
export PATH=$ANDROID_SDK_ROOT/tools/:$ANDROID_SDK_ROOT/platform-tools/:$ANDROID_SDK_ROOT/build-tools/19.1.0/:$PATH

 

PS: bei Debian (sid) musste ich noch ein wenig nachhelfen, so dass die Android-SDK auch korrekt funktioniert:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install lib32z1 lib32stdc++6

 

Beispiel-App für Android erstellen

ionic start planet-ubuntuusers
cd planet-ubuntuusers
rm -rf www/
git clone https://github.com/voku/planet-ubuntuusers-app www
ionic platform android
ionic build android

Man kann die App nun im Browser (ionic serve), im Android Emulator (ionic emulate android) oder direkt auf seinem Android-Gerät (ionic run android) ausprobieren!!!

 

Links

Es folgen ein paar Links zur App / API / Dokumentation  und zum Beispiel-Quellcode

ANDOIRD APP-DOWNLOAD:
 http://suckup.de/planet-ubuntuusers-json/PlanetApp-debug.apk

QUELLCODE ZUR APP:
https://github.com/voku/planet-ubuntuusers-app

SCREENSHOT:
Planet App

JSON-API: 
http://suckup.de/planet-ubuntuusers-json/json.php

HTML-OUTPUT VIA TWIG:
http://suckup.de/planet-ubuntuusers-json/

QUELLCODE ZUR API:
https://github.com/voku/planet-ubuntuusers-json (in zirka 2 Minuten geschrieben & deployed -> composer is great!!!)

 

DOKUMENTATION:
https://docs.angularjs.org/
http://ionicframework.com/docs/
http://cordova.apache.org/

Kurztipp: lokalen offenen Port finden (bash)

Habe soeben folgende Funktionen zu meinen dotfiles hinzugefügt, um einen freien lokalen Port zu finden. Diese werden wiederum verwendet, um z.B. die “phpserver“-Funktion auszuführen.

# -------------------------------------------------------------------
# netstat_used_local_ports: get used tcp-ports
netstat_used_local_ports()
{
  netstat -atn | awk '{printf "%s\n%s\n", $4, $4}' | grep -oE '[0-9]*$' | sort -n | uniq
}

# -------------------------------------------------------------------
# netstat_free_local_port: get one free tcp-port
netstat_free_local_port()
{
  read lowerPort upperPort < /proc/sys/net/ipv4/ip_local_port_range
 
  # create a local array of used ports 
  local all_used_ports=($(netstat_used_local_ports))

  for port in $(seq $lowerPort $upperPort); do
    for used_port in "${all_used_ports[@]}"; do
      if [ $used_port -eq $port ]; then
        continue
      else
        echo $port
        return 0
      fi
    done
  done 
}