Blackfire PHP-Profiler: Fire up the Performance

Am Wochenende habe ich mal wieder ein neues Tool ausprobiert: „Blackfire“ ist ebenso wie „Insight“ von SensioLabs entwickelt und kann die Performance einer PHP-Anwendung „on the fly“ analysieren und visualisieren.

Die Installation besteht aus folgenden Komponenten:

  • Probe: dies ist die PHP-Extension welche wir auf dem Server installieren
  • Agent: Dies ist ein Programm, welches ebenfalls auf dem Server installiert wird und die Performance-Daten zu blackfire.io weiterleitet, wo diese dann visualisiert werden
  • Client (optional): ein CLI-Tool um PHP-Profiling auf der Kommandozeile auszuführen
  • Companion: dies ist eine Chrome-Extension, welche auf Knopfdruck das PHP-Profiling ausführt
  • Website: die blackfire.io Webseite zur Darstellung der Ergebnisse

Die Installationsanleitung ist innerhalb von zirka 5 Minuten abgearbeitet und schon kann man schnell und bequem die Leistung / Performance von Änderungen testen und die entsprechenden Ergebnisse miteinander vergleichen.

blackfire.io
blackfire.io: Beispiel-Profile von „http://moelleken.org

 

PS: wer noch mehr Information benötigt sollte sich Xdebug lokal installieren bzw. aktivieren und die Profile-Daten anschließend via WinCacheGrind (Windows) oder direkt via KCachegrind (Linux) auswerten und visualisieren.

KCachegrind
KCachegrind

 

Git (Introduction + Workshop) am 22. Januar 2015 – also heute!

Wer heute Zeit und Lust hat, kann in Düsseldorf ab 19 Uhr bei der trivago GmbH (Bennigsen-Platz 1) beim monatlichen Treffen der „PHP Usergroup Düsseldorf“ mehr über „Git“ erfahren.

Bisher haben sich bereits 58 Leute für das Treffen auf www.meetup.com/PHP-Usergroup-Duesseldorf/ angemeldet. Wenn du ebenfalls teilnehmen möchte, melde dich einfach vorher bei „www.meetup.com“ an und teilt dem Veranstalteter (PHP Usergroup Düsseldorf – vorheriger Link) mit, dass du kommst. So kann man sich auf die zu erwarteten Teilnehmer einstellen, danke!

git

Eine Einführung in das Versionskontrollsystem Git in Kombination mit einem „on the fly“ Workshop. Damit du am Workshop teilnehmen kannst, solltest du deinen Laptop mitbringen und folgende Dinge schon mal vorbereitet haben:

* installiere Git (http://git-scm.com/­)
* erstelle einen Account bei Github (https://github.com/­)
* erstelle einen SSH-Key und hinterlege diesen bei github (https://help.github.com/articles…­)

Dashboard-Leak for the next @PHPUGDus meetup on thursday #Git #Workshop
Dashboard-Leak for the next @PHPUGDus meetup on thursday #Git #Workshop 

Mehr Infos zum Event gibt es hier!

Webseite: http://www.meetup.com/PHP-Usergroup-Duesseldorf/events/219616098/
Twitter: https://twitter.com/phpugdus

PS: Und wer glaubt, dass in der PHPUGDus nur über PHP gesprochen wird, sollte sich eines besseren belehren lassen und sich einmal die Titel der letzten Meettups anschauen. ;) Also ggf. bis später und allen noch einen erfolgreichen Tag!

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.