Kategorien
Technisches

WordPress mit Object Cache (memcached/Redis) für Entwickler

Zielgruppe

Entwickler von WordPress Themes und/oder Plugins, die $wpdb benutzen und sich jetzt wundern, warum die Website spinnt.

Intro – Caching

Caching beschleunigt Webapplikationen – so auch WordPress. Es gibt einen Schwung Caches, welche alle ihre Eigenarten haben. Für den Entwickler eines WordPress Plugins oder eines WordPress Themes ist dabei besonders der Object Cache (memcached oder Redis) zu beachten.

  • Viele andere Caches funktionieren im Hintergrund, ohne dass der Programmierer sich Gedanken um die Invalidierung machen muss
  • Komplette Seiten-Caches müssen wohlüberdacht sein und liegen eher im Verantwortungsbereich des Seitenbetreibers

Hier soll es also um die Object Caches (z.B. memcached) gehen und was man bei der Programmierung von Applikationen unter WordPress dafür beachten muss.

Funktionsweise von Object Caches

Object Caches sind einfache Key/Value-Speicher. Wenn man zum Beispiel mit einer aufwändigen Berechnung und vielen Datenbankabfragen ein Ergebnis bekommen hat, dann kann man dieses zwischenspeichern, um es bei späteren Aufrufen der Seite wider verwenden zu können, ohne die Berechnung und die Datenbankabfragen noch einmal machen zu müssen.

Der errechnete Wert (z.B. „42“) wird dann unter einem Key (z.B. „Antwort“) im Cache gespeichert. Bei der Speicherung wird neben dem Key und dem Wert auch noch eine Lebenszeit angegeben, nachdem der Wert automatisch invalidiert wird. Gibt man keine Lebenszeit an, dann muss man sich darum kümmern, dass der Wert bei einer Änderung der zugrundeliegenden Daten automatisch invalidiert wird.

Object Caches in WordPress

Unter WordPress kann man die Funktionen benutzen:

Wichtig ist aber zu wissen, dass WordPress diese Funktionen auch selbst benutzt. Wenn kein Plugin installiert ist, welches einen Object-Cache bereitstellt, dann cacht WordPress die Werte nur für die Dauer des Aufrufs. Wird allerdings ein Caching-Plugin installiert, dann werden die Werte auch über Aufrufe hinweg gespeichert – und das kann dann bei unachtsamer Programmierung zu Problemen führen.

Wann Invalidieren von Daten notwendig ist

WordPress bietet verschiedene Abstraktionsebenen.

  • Auf der obersten Ebene haben wir ein paar Funktionen wie the_title() und so, mit denen wir einfach in Templates auf Daten zugreifen können. Diese Funktionen nutzen den Cache ohne unser zutun.
  • Eine Ebene darunter befinden sich die Funktionen, mit denen man auf die Daten zugreifen kann, die WordPress in der Datenbank gespeichert hat. Hier kann man auch Daten ändern. wp_update_user(), get_post_meta() und so. Auch diese Funktionen nutzen den Cache, und wenn man mit ihnen (mit den Update-Funktionen) Daten ändert, dann invalidieren sie auch automatisch den Cache.
  • Als unterste Ebene stellt WordPress aber die $wpdb-Klasse zur Verfügung, mit denen man mehr oder weniger direkt mit der Datenbank interagieren kann. Hier umgeht man den Cache. Für Daten, die man so aus der Datenbank holt wird nicht zuerst der Cache befragt, sondern direkt die Datenbank. Gleiches gilt auch für Updates: Der Cache wir nicht invalidiert.

Das bedeutet, dass man bei der Nutzung der wpdb-Klasse vorsichtig sein muss. Ein Beispiel verdeutlicht das:

Beispiel

Zuerst schauen wir uns an, wie das funktioniert, wenn man die Funktionen eines höhren Abstraktionslevels benutzt:

  • Ein Benutzer schaut sich einen Post an. Dieser wird durch get_post() o.ä. aus der Datenbank geholt. Da das potentiell aufwändig ist wird das Ergebnis der Datenbankabfrage im Cache abgelegt.
  • Ein weiterer Benutzer schaut sich den gleichen Post an. WordPress holt die Daten nicht mehr aus der Datenbank, sondern aus dem Cache.
  • Mittels wp_update_post() wird der Post geändert. WordPress kümmert sich automatisch darum, dass der Cache invalidiert wird.
  • Ein dritter Benutzer schaut sich den Post an. Er wird wieder aus der Datenbank geholt, denn es gibt ja keinen gültigen Cache-Eintrag mehr für diesen Post. Das Ergebnis wird wieder im Cache abgelegt für den vierten Benutzer

Jetzt das Gleiche, nur dass wir zum Update des Posts nicht wp_update_post() benutzen, sondern direkt mit $wpdb arbeiten:

  • (identisch) Ein Benutzer schaut sich einen Post an. Dieser wird durch get_post() o.ä. aus der Datenbank geholt. Da das potentiell aufwändig ist wird das Ergebnis der Datenbankabfrage im Cache abgelegt.
  • (identisch) Ein weiterer Benutzer schaut sich den gleichen Post an. WordPress holt die Daten nicht mehr aus der Datenbank, sondern aus dem Cache.
  • Mittels wpdb wird der Post geändert. Da wir die Caching-Schicht umgehen bekommt der Cache nichts von der Änderung mit und der Cache wird nicht invalidiert.
  • Ein dritter Benutzer schaut sich den Post an. Da es noch einen gültigen Cache-Eintrag gibt bekommt der Benutzer die alte Version des Posts zu sehen. Das ist falsch uns sollte vermieden werden.

Man hat als Programmierer jetzt also drei Möglichkeiten:

  • Entweder benutzt man nur die Funktionen des höheren Abstraktionslevels (wp_update_post() o.ä.)
  • Oder man speichert seine Daten in eigenen Tabellen, so dass man sicher sein kann, dass WordPress nicht „von Haus aus“ darauf zugreift.
  • Oder man invalidiert den Cache nach Updates manuell

So invalidiert man Daten

Das kann man sich im Quelltext von WordPress schön anschauen, wie das die WordPress-eigenen Funktionen machen. In der Funktionsreferenz kann man nach „clean cache“ suchen, da findet sich sicherlich was passendes:

https://developer.wordpress.org/?s=clean+cache

Disclaimer

Dieser Text ist nur schnell für den Eigengebrauch runtergeschrieben und wurde nicht noch mal „Kontroll-gelesen“. Falls das jemand vor mir schafft werden Verbesserungen und Korrekturen gerne per Mail entgegen genommen.

Kategorien
Technisches

WordPress Media Upload broken

An Update to WordPress core broke media upload on all my sites. The update was on 2019-10-14, but problems arised now, when november begun.

Setup

We use a special directory structure which is like this:

  • wp/
  • uploads/
  • wp-content/
  • index.html
  • wp-config.php

With this layout it’s possible for us to have the different parts in different places: wp is a clean, unmodified WordPress checkout, uploads contains all the media files and wp-content contains the code for the website.

With setting constants WP_SITEURL, WP_CONTENT_DIR, WP_CONTENT_URL, WP_PLUGIN_DIR and WP_PLUGIN_URL along with UPLOADs this worked fine. However:

define(‚UPLOADS‘,‘../uploads‘);

was needed, because _wp_upload_dir() calculates the uploads-directory by appending UPLOADS to ABSURL – and ABSURL is in my wp-folder.

Problem

Recent Changes in WordPress Core forbid creating directories with „../“ in their path. Uploading files works, but creation of the „2019/11/“-folder fails.

https://core.trac.wordpress.org/ticket/48316

https://foliovision.com/2019/11/wordpress-unable-to-create-directory

https://wordpress.stackexchange.com/questions/352042/install-wordpress-with-custom-directory-layout-without-breakting-media-upload

Kategorien
Technisches

Uncaught ImagickException: not authorized @ error/constitute.c/ReadImage/412

Bei Imagick gab es eine Sicherheitslücke, welche durch eine Änderung der Standardkonfiguration gefixt wurde. Die Konfigurationsdatei ist (bei mir, Ubuntu 16.04 LTS) /etc/ImageMagick-6/policy.xml. Hier wurde dem ImageMagick verboten PDF-Dateien (und mehr) zu lesen. Wenn man (wie ich) aber PDF-Dateien zu JPEGs umwandeln will, dann führt das zu o.g. Fehler.

Die Relevante Zeile in der Datei war:

<!-- disable ghostscript format types -->
<policy domain="coder" rights="none" pattern="PS" />
<policy domain="coder" rights="none" pattern="EPS" />
<policy domain="coder" rights="read|write" pattern="PDF" />
<policy domain="coder" rights="none" pattern="XPS" />

Wie man sieht habe ich einfach auf PDF die Rechte „read|write“ statt „none“ gegeben.

Zusammenspiel mit PHP

In meinem konkreten Fall äußerte sich der Bugfix (Funktionalität ging kaputt) erst viel später, als das PHP (als FPM) neu gestartet wurde. Ebenso wirkte sich meine Konfigurationsänderung erst aus als ich das PHP neu gestartet hatte.

Kategorien
Musik

Chorsatz SATB Sowieso von Mark Forster

Wir haben am 2. September 2018 „Sowieso“ von Mark Forster mit Sing’n’Swing in der Versöhnungskirche in Salmünster gesungen.
Hier sind die Noten.

Anlass was der „Hit from Heaven Sonntag„, den die evangelische Kirche Hessen-Nassau jedes Jahr zusammen mit Hitradio FFH veranstaltet.

Als Lied wurde dann von den FFH-Hörern eben „Sowieso“ von Mark Forster gewählt. Das wollten/sollten wir also singen. Da wir für das Lied aber keinen geeigneten Chorsatz gefunden haben habe ich selbst einen geschrieben. Er ist für vierstimmig für gemischten Chor SATB geschrieben:

  • sehr nah am Original: Abgesehen davon, dass es bisschen kürzer ist als das Original kann man da mit der Originalaufnahme mitsingen.
  • vierstimmig SATB
  • einmal an Anfang teilt sich der Sopran ganz kurz und einmal der Bass ganz kurz
  • man braucht einen Solisten, der die Strophen singt (der soll sich lieber an das Original halten als an das, was ich zur Orientierung notiert habe)
  • Rhythmische Begleitung wäre auch gut, ich hatte das einfach auf dem Cajon begleitet

Den Satz (also die Noten) kann von mir aus jeder gerne verwenden, die Musik ist aber halt nicht von mir :-D Aber nachdem sowohl die EKHN als auch FFH die Noten zum Download angeboten hatten darf ich das wohl auch, oder? Deshalb hier das PDF und auch die MuseScore-Datei:

Sowieso Chorsatz SATB als MuseScore und Music-XML

Sowieso Chorsatz SATB als PDF

Kategorien
Technisches

Firefox HTTP/2 & IPv6: Webserver Subdomain Configuration Pitfall

Conditions

  • two (or more) subdomains (same domain)
  • …share a common wildcard ssl certificate
  • on the same host (same IPv4-address)
  • but with different IPv6-addresses
  • client: Firefox (only Firefox has this behavior)
  • use HTTP/2
  • use IPv6

Expected behavior:

  • foo.example.com in location bar shows foo.example.com
  • bar.example.com in location bar shows bar.example.com

Seen behavior

Requests for the second host (bar) go to the first host (foo).

Explanation

With HTTP/2 Firefox shares connections to webservers („pooling“) to speed up page loading by omitting handshake and tcp slow start. Firefox determines which connections can be pooled together not by looking at the hostname, but by looking at the IPv4-address and the certificate. If the IPv4 address of the second host (bar) matches the IPv4-address of the first host (foo) AND the certificate used for foo also matches bar then the connection to foo is reused for bar.

Problem

The webserver may not be configured to show the contents of bar when someone connects to the IPv6-Adress of foo. Webserver administrators who were happy about the fact that with IPv6 there’s no need for SNI and name based virtual hosting anymore (like me) may have configured their webservers in the false assumption that if an IPv6 address is published for hostname foo incoming connections to that host will go to that IP address.

The behavior of Firefox is highly unexpected – or simply wrong.

Workaround

There are many obvious workarounds, but all of them have disadvantages.

  1. use different certificates (cheap nowadays) or
  2. use the same IPv6 address (use name based virtual hosting and SNI even when using IPv6) or
  3. use http status code 421 to answer „misguided“ requests

Links

Bugzilla: Firefox should decide whether reuse connection separately for IPv4 and IPv6

Daniel Steinberg: HTTP/2 connection coalescing

RFC 7540 Hypertext Transfer Protocol Version 2 (HTTP/2): 9.1.1. Connection Reuse

Kategorien
Fotos

Föhr Fotos

Ein paar Fotos, die wir im Urlaub auf Föhr gemacht haben. Eigentlich wollte ich zuerst schreiben, dass ich die Fotos gemacht habe, aber beim Durchsehen ist mir aufgefallen, dass ein paar der coolsten Fotos meine Kinder gemacht haben :-)

DSC_7317

DSC_7318

DSC_7334

DSC_7346

DSC_7352

DSC_7353

DSC_7381

DSC_7382

DSC_7389

DSC_7466

DSC_7493

DSC_7507

DSC_7593

DSC_7631

DSC_7978

DSC_8095

DSC_8101

DSC_8102

DSC_8128

DSC_8167

DSC_8222

DSC_8227_1

DSC_8230

DSC_8233

DSC_8236

DSC_8255

DSC_8301

DSC_8305

DSC_8311

DSC_8312

DSC_8326

DSC_8553

DSC_8687

Kategorien
Technisches

Charset, Encoding & Collation (MySQL „utf8mb4“)

Charset

Das Charset (der Zeichensatz) ist EIGENTLICH eine definierte Menge an Buchstaben. Da nutzen wir „Unicode“ – das ist das, was man heutzutage so hat. Wenn man aber „Charset“ oder „Zeichensatz“ sagt, dann meint man i.d.R. das Encoding.

Encoding

Das Encoding ist die Kodierung von Zeichen in Bytes. Fast alle üblichen Kodierungen sind Supersets von US-ASCII, gleichen sich also in den wichtigesten, üblichen Zeichen.

UTF-16 ist da eine Ausnahme, weil das für JEDEN Buchstaben zwei Bytes benutzt, deshalb mit NIX kompatibel ist außer mit sich selbst und das deshalb auch NIEMAND benutzt (Außer Microsoft natürlich – und Java, weil wenn’s eine bekloppte Idee gibt, dann macht Java da natürlich mit).

Das wichtigste Encoding (mit dem bei uns alles gemacht sein sollte) ist UTF-8. Ich kann das nicht so gut erklären wie Computerphile:

Youtube: Computerphile on UTF-8 (Must-see, 10 min.)

Als UTF-8 in das MySQL eingebaut wurde haben sie aber nur ein Subset genommen, und zwar gibt es die Beschränkung, dass es nur maximal 2 Bytes haben kann. Das kann zu Problemen bei irgendwelchen asiatischen und klingonischen Sprachen führen. Deshalb gibt es jetzt utf8mb4, welches maximal 4 Bytes hat.

Collation

Man hat jetzt zwar die Möglichkeit die Zeichen alle zu Codieren, jedoch hat man dadurch noch keine Interpretation der Zeichen als Teil des Alphabets. Für deutsche ist ein „ß“ so etwas wie „ss“ und ein „ö“ so ähnlich wie „oe“, ein „ë“ aber nicht wie ein „ee“.

Deshalb brauchen wir die Collation: Im türkischen sind i und I zwei unterschiedliche Buchstaben, im schwedischen kommt ä hinter z, im Lateinischen sind „U“ und „V“ äquivalent und so weiter. Damit das richtig sortiert wird gibt es die Kollationen.

Eine Kollation ist demzufolge die Konkretisierung eines Encodings bezüglich der Sortierung. Deshalb beginnt der Name der Collation auch immer mit der Name des Encodings.

„utf8mb4“ hat als Default-Collation z.B. „utf8mb4_general_ci“ – das könnte man auf „utf8mb4_german1_ci“ umstellen (für Duden-Reihenfolge) oder auf „utf8mb4_german2_ci“ für Telefonbuch-Reihenfolge. Die Unterschiede sind aber weniger wichtig. Relevant ist vor allen Dingen die Unterscheidung zwischen utf8 und utf8mb4 als Chars^W Colla^W Encoding.

Kategorien
Allgemein Technisches

Papiermenschens Cyber

Wenn mir ein Papiermensch…

Ein Papiermensch ist ein Mensch, der Dinge, die am Bildschirm zu lesen sind, nicht so wichtig findet wie die Dinge, die auf Papier ausgedruckt sind. Menschen, die Informationen ausdrucken um sie zu lesen. Menschen, die einer 2048-RSA-Schüssel (von einer CA signiert) als unsicher erachten, aber ein bisschen Gekritzel mit Kuli auf einem Papier sicher finden.

Wenn mir also ein Papiermensch sagt, ich solle etwas über „Cyber“ schreiben, was schreib ich dann? Papiermenschen finden den Duden gut. Im Duden steht, dass die Vorsilbe „Cyber“ Dinge kennzeichnet, die eine von Computern generierte Scheinwelt betreffen. Das hört sich nach „VR“ an, aber es soll eigentlich über Mailserver und Netzwerksicherheit gehen. Wie unterscheidet sich die Sicherheit eines Computernetzwerkes von der Cybersicherheit eines Computernetzwerkes?

Wisst ihr, was ich glaube? Ich glaube „die Sicherheit von Computern“ ist für diese Menschen zum Beispiel, dass einem kein Computer auf den Fuß fällt, denn da könnte sich jemand verletzen. Auch darf ein Computergehäuse keine scharfen Kanten haben. Das ist „die Sicherheit von Computern“.

Die „Cybersicherheit“ hingegen ist dann das, was ich unter Sicherheit verstehe.

Sicherheit von Computernetzwerken

Niemand stolpert über Netzwerkkabel und die Computer sind so im Regal festgeschraubt, dass sie nicht rausfallen können.

Cybersicherheit von Computernetzwerken

Die Computer tun das was sie sollen statt irgendwelche Angriffe auf Infrastruktur zu fahren.

Cyber

Cyber: Das Wort haben in den 90ern die Menschen benutzt, die noch kein Internet hatten, wenn sie den Menschen, die schon Internet hatten, das Internet erklärt haben. Das war damals schon lächerlich.

Kategorien
Allgemein

42

Wikipedia: 42 (Antwort)

Amazon: Per Anhalter durch die Galaxis

Kategorien
Allgemein

We Will Rock You (acapella)

Wir haben mit Takt9, unserem Quintett We will Rock you von Queen aufgenommen: