The Amazon CloudFront - A play ground



Was'n das?

Vor einiger Zeit hatte ich aus beruflichen Gründen das Vergnügen, mich mit dem Amazon S3 Webservice auseinander setzten zu dürfen. Nach ein bisschen Einlesen muss ich gestehen, Feuer und Flamme gewesen zu sein.

Das Ziel war, einen praktikablen Weg zu finden, von Benutzern hochgeladen Bilder in verschiede Größen umzurechnen und sie dann auf einem externen Server zu lagern (also eben ein CDN zu verwenden). Somit sollten Bandbreite, Speicherplatz und auch Kosten gespart werden. Soweit so gut - so spannend.

Dem ersten Ansatz folgended (Bilder vom Benutzer hochladen lassen, umrechen und auf den Amazon S3 Server schieben und die Links in den Webseiten entsprechend setzten) wurde die Sache dann realisiert und gefiehl. Nicht perfekt, aber praktikabel und erfolgreich im Einsatz.

Nach einigem Nachgrübeln wollte ich aber mehr und folgende Punkte kamen mir in den Sinn:

  1. Ich will nichts mehr von dem statisches Zeugs auf der orginalen Domain haben - mit Ausnahme der Originale bei Bildern. Damit geht der gesamte Traffik der User-Agents "irgendwo" anders hin - und das schneller und stabiler.
  2. Ich will nicht, wie in der aktuellen Lösung, schon vor der Verwendung die verschiedenen Bildgrößen errechnen müssen.
  3. Ich will so wenig wie möglich Konfigurationsaufwand und trotzdem flexibel bleiben für zukünfte Entwicklungen.
  4. Ich will es derart entwickeln, so dass ich es in bestehende Produkte integrieren kann.
Nun, das war schon mal ein Menge "ich will". Schwierig - aber nicht unmöglich. Einmal abgesehen davon muss man sich nach oben und nicht nach unten orientieren ;)

Der Weg zum Ziel

Da ich mich ja nun schon ein wenig auskannte, habe ich weiter in der Doku des S3 gelesen, aber keine vernünftige Lösung für folgendes Problem gefunden: Was tun, wenn ich eine neue Bildgröße brauche? Oder über ein Bild das erste mal angefordert wird? Bei S3 ist er nur möglich statischen Content zu lagern und die Sache mit den Error-Seiten ist auch kein passender Weg.

Bingo! - Custom Origin war das Zauberwort der Stunden. Geniale Sache, glänzende Augen, Möglichkeiten in Hülle und Fülle. Und funktioniert ganz einfach:

Wird von einer Webseite zum Beispiel ein Bild mit dem Link http://dzi4vjb1ti3sh.cloudfront.net/img/common/mosw.jpg angefordert und es liegt dort nicht, kann man den Server anweisen sich diese Ressource von wo anders zu holen und zu speichern. Alle weiteren Zugriffe werden dann immer von dort (dem Wolker'l eben) bedient. Boah - Ein Woge der Begeisterung waberte durch mein altes Gehirn.

Aber immer langesam mit den jungen Pferden - Schritt für Schritt

Im ersten Schritt habe ich erstmal auf meinem Server die Beispielanwendung vorbereiten. Nun, Anwendung ist vielleicht etwas übertrieben, aber eben eine Sub-Domain eingerichtet und so.

Der zweite Schritt war die Anmeldung bei Amazon. Das war Ratz-Fatz getan. Und so wie unter dieser Ableitung angegeben, war auch der CloudFront-Service in wenigen Minuten aktiviert.

Et voila - - die Basics funktionieren. *Applaus* Ja, so schnell kann es gehen.

Wer dann noch Lust hat, kann zum Beispiel per CNAME eine Sub-Domain wie zB. static.example.com auf seinen Platz in der Cloud verbiegen und das ganze ist für den User transparent. Gut, in den HTTP-Header meldet sich der Service von Amazon noch, aber ein gute Schritt ist es alle mal. Geiler geht nicht - echt nicht.

Nun aber zu Schritt 3 - dem wohl entscheidenden Schritt. Ich will das Bild in verschiedenen Größen.

Dazu war erst mal die Überlegung einer passenden URL notwending. Spontan und einfallsreich wie ich bin, kam mir /img/common/100x100/mosw.jpg in Sinn. Dazu bedarf es aber noch weiterer kleiner Arbeiten.

Zuerst einmal habe ich im Verzeichnis /img/ eine kleine Rewrite-rule angelegt, die mir Zugriffe auf nicht vorhandene Bilder umleitet.

RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} -s [OR]
  RewriteCond %{REQUEST_FILENAME} -l [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^.*$ - [NC,L]
  RewriteRule ^.*$ index.php [NC,L]

Diese Regel gilt jetzt zwar für alle nicht gefunden Dateien, aber für den Anfang ist es okay.

Dann, eine Stunde und ein paar Zeilen PHP-Code (exakt 53) später, Links wie der folgende funktionieren endlich perfekt:
http://dzi4vjb1ti3sh.cloudfront.net/img/common/50x50/mosw.jpg.
Die HTTP-Header zeigen beim ersten Aufruf ein "Cache miss", ab dann ein "Cache hit" an.

QED!

Danke für Ihre Aufmerksamkeit ;)