Einen Server auf HTTP2 umziehen – eine IT Story!

HTTP/2 ist geil, das durfte ich neulich in der ix 02/2018 lesen. Und ich war überzeugt: Jetzt muss ich das ganze auch mal auf ein Produktivsystem ausrollen!
… was dann folgte war natürlich wie immer: Es hat nicht geklappt und es wollte einfach nicht klappen. Hier also eine Kurzgeschichte zu: „So läufts nunmal in der IT“.

Erstmal vorab: Ja, ich wusste natürlich schon was HTTP/2 so bietet:
– Ein binäres Protokoll, somit also etwas weniger Übertragungsmenge nötig
– Eine Verbindung die alle Daten fetcht, somit kein erneuter TCP und SSL Handshake nötig
– Dank nur einer Verbindung kein Problem mit TCP Slow Start und somit bessere Ausnutzung der Bandbreite

Das sind zumindest die Sachen die mir so im Kopf blieben.
Und ja: Ich hatte die Umstellung eines Apache2 Webservers auf HTTP2 schon auf einem Testsystem geübt und genau deshalb habe ich gesagt „Das mach ich tagsüber, geht ja schnell!“

Also ran ans Echtsystem, natürlich vormittags wo am meisten Betrieb herscht. Macht aber ja nix denn wir brauchen ja nur einen Neustart des Apachen und schon läuft alles. Das merkt keiner!
Zuerst brauchen wir für Ubuntu 16.04 ein Fremdrepo denn der bei Ubuntu beinhaltete Apache 2.4.18 kann kein HTTP/2:

add-apt-repository ppa:ondrej/apache2
apt-get update
apt-get dist-upgrade
apt-get autoremove
apt-get clean

Und fertig ist der Apache in Version 2.4.29.

Bei der Installation hab ich ihn gleich unsere angepassten Konfig-Dateien ‚/etc/apache2/apache2.conf‘ und ‚/etc/logrotate.d/apache2‘ aktualisieren lassen und unsere Änderungen wieder neu eingebaut.
Nicht dass in den neuen Konfig-Dateien irgendein Parameter sein muss der nicht da gewesen wäre wenn ich die alten behalten hätte.
Sehr schön dass man beim Updaten gefragt wird und sogar direkt ein Diff der Unterschiede ansehen kann!

Nun nochmal in die Datei ‚/etc/apache2/apache2.conf‘ und dort ganz oben den (neuen) Parameter ‚Protocols‘ eintragen:

Protocols h2 h2c http/1.1

Das heißt dass wir zuallerst http2 über ssl unterstüzen (h2) dann ohne SSL (h2c) und dann das normale http1 (http/1.1).
HTTP/2 ohne SSL ist übrigens eher unwichtig weil wohl alle modernen Browser HTTP/2 ausschließlich über SSL sprechen!

Jetzt noch schnell das HTTP/2 Modul aktivieren, und fertig ist alles:

a2enmod http2

Ein Neustart des Apachen führte dazu dass: Sich nichts geändert hat 🙁
Es wollte einfach kein HTTP/2 rauskommen aus der Leitung!

Erster Schritt wie immer: Blick in die Logfiles!
In dem Fall war es das serverweite Logfile ‚/var/log/apache2/error.log‘ und es sprach:

[Wed Feb 28 09:50:41.195499 2018] [http2:warn] [pid 23717] AH10034: The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.

Na wunderbar! mpm_prefork brauche ich weil ich PHP direkt als Apache-Modul nutze. Wenn ich also mpm_prefork deaktiviere geht php nicht mehr. Naaa toll…
Bei meinem Testsystem ist dieses Problem nicht aufgetreten weil ich dort PHP-FPM nutze. Mist!

Also mal schnell auf PHP-FPM umschalten:

apt-get install php-fpm libapache2-mod-fastcgi
a2dismod php7.0
a2dismod mpm_prefork
a2enmod mpm_event
a2enmod actions
a2enmod fastcgi
a2enconf php7.0-fpm

Und nach einem Neustart feststellen: Läuft nicht, der Apache mag nicht!
Na prima. Echtsystem und der Apache kommt nicht mehr hoch. Argh!!!

Nach Blick in die Logfiles offenbarte sich ein Konfigurationsfehler denn der Parameter

php_value engine off

existiert nicht mehr unter PHP-FPM. Auch etwas was mir auf einem simplen Testsystem natürlich nicht aufgefallen wäre.

Nun also noch schnell in die globale Konfig ‚/etc/apache2/apache2.conf‘ das folgende rein:

AddHandler php70-fcgi-www .php
Action php70-fcgi-www /php70-fcgi-www
Alias /php70-fcgi-www /usr/lib/cgi-bin/php70-fcgi-www
FastCgiExternalServer /usr/lib/cgi-bin/php70-fcgi-www -socket /run/php/php7.0-fpm.sock -pass-header Authorization

<Directory "/usr/lib/cgi-bin">
 Require all granted
</Directory>

<Directory /var/www/html/nophp>
 <Files "*.*">
 SetHandler !
 </Files>
</Directory>

Und in der Default-Site ‚etc/apache2/sites-available/000-default.conf‘ den Handler für alles PHP-artige aktivieren:

<FilesMatch ".+\.ph(p[345]?|t|tml)$">
 SetHandler php70-fcgi-www
</FilesMatch>

Und schon gehts. War doch ganz einfach 🙁
Ja, ich hätte ein deutlich vollständigeres Testsystem nehmen sollen.
Und ja, ich hätte die Arbeit nicht direkt am Vormittag machen sollen wo jeder auf die Webseite zugreifen will, obwohl ich dachte es dauert nur 2 Minuten.

Selbstverständlich hätte ich das Echtsystem auch vorher über die Failover-IP aufs Standby System leiten können.
Problem ist nur: Dann kann man halt auch schlecht testen ob nun alles geht, aber zumindest den nicht mehr startenden Apache hätte ich in Ruhe debuggen können.
Aber warum auch? Bei meinem Test dauerte es doch nur 2 Minuten!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.