GeoIP mit Varnish Cache und Magento

10. Juni 2016
GeoIP mit Varnish Cache und Magento

Online-Shops, die in mehreren Ländern und Sprachen verkaufen wollen, möchten ihre Kunden am besten automatisch in den richtigen Substore leiten. Dies ist besonders wichtig, wenn Produktsortimente und Preise länderspezifisch sind und man Falschbestellungen und Reklamationen gering halten will.

Viele Länder

Die beste Möglichkeit hierfür ist GeoIP, mithilfe derer mittels IP-Adresse des Seitenbesuchers eine Datenbank durchsucht wird, um das Land des Besuchers zu ermitteln. Mit dieser Information wird der Besucher dann in den jeweiligen Substore weitergeleitet, sofern er sich nicht bereits im selbigen befindet.

Für Magento gibt es einige wirklich gute Module, die genau dies ermöglichen. Doch was macht man, wenn man Varnish Cache nutzt? Die Länderzuordnung in Magento nützt nicht viel, wenn die Anfragen bereits durch Varnish beantworten werden. Die einfachste Lösung für das Problem ist, die GeoIP-Abfrage direkt in Varnish vorzunehmen. Glücklicherweise unterstützt Varnish Cache seit der Version 3.0 sog. Vmods, kleine Funktionsbibliotheken, die man aus VCL ansprechen kann. Ein solches Vmod für GeoIP gibt von Lee Doolan, das sich einfach kompilieren lässt. Hat man dieses Vmod in Varnish installiert, lässt sich das Regelwerk ziemlich einfach in VCL definieren:

# import GeoIP vmod import geoip; sub vcl_recv { ... ### # GeoIP store switch # # Apply if # - URL doesn't point to a static folder # - User-Agent doesn't look like a bot ### if (!(req.url ~ "^/(downloader|errors|js|media|skin)/") && !(req.http.User-Agent ~ "(?i)(bot|crawler)"))) { if (geoip.country(req.http.X-Forwarded-For) == "DE") { if (!(req.url ~ "^/de_")) { # German visitors should go in German store error 750 "http://" + req.http.host + "/de_de/"; } } elsif (geoip.country(req.http.X-Forwarded-For) == "AT") { if (!(req.url ~ "^/at_")) { # Austrian visitors should go in Austrian store error 750 "http://" + req.http.host + "/at_de/"; } } else { if (!(req.url ~ "^/en_")) { # Other countries than AT or DE should go in the English store error 750 "http://" + req.http.host + "/en_en/"; } } } ... } ... sub vcl_error { if (obj.status == 750) { set obj.http.Location = obj.response; set obj.status = 302; return(deliver); } ... }

Und schon werden die Besucher in den jeweiligen Substore geleitet während der Varnish Cache immer noch die Seiten blitzschnell ausliefert.