
Weltweit replizierte Dienste für den Rest von uns

Nach dem Lesen endloser Serverless-Horrorgeschichten hast du dich entschieden, deine Anwendung auf dem aktuellen Liebling des Internets, Hetzner, zu deployen. Aber jetzt steckt dein Server an einem Ort fest, während deine Nutzer über die ganze Welt verteilt sind und unter schrecklicher Latenz leiden. Was kannst du tun? Lass mich dir Geolocation-DNS-basiertes Routing vorstellen!
Das Problem: Globale Latenz
Wenn du Anwendungen in einer einzelnen Region hostest, erleben Nutzer aus anderen Teilen der Welt höhere Latenzzeiten. Wenn dein Server beispielsweise in Deutschland steht, könnten Nutzer aus Australien Verzögerungen von 300ms oder mehr erleben. Diese Latenz kann die Benutzererfahrung erheblich beeinträchtigen, besonders bei interaktiven Anwendungen. Natürlich könntest du einfach mehr Server in mehr Regionen aufstellen, aber woher soll ein Nutzer wissen, mit welchem Server er sich verbinden soll? Du willst ja nicht eu.deine-domain.com, us.deine-domain.com, au.deine-domain.com, oder? Sondern einfach deine-domain.com, die zum nächstgelegenen Server weiterleitet.
Anycast vs. DNS-basiertes Routing
Wenn du deine Anwendung global bereitstellen willst, hast du zwei Optionen: Anycast und DNS-basiertes Routing.
Anycast
Eine mögliche Lösung für globales Routing ist die Verwendung von Anycast-IP-Adressen. Normalerweise wird eine IP-Adresse nur von einem Gerät verwendet. Mit Anycast kann eine IP-Adresse von mehreren Geräten an mehreren Standorten verwendet werden. Die Magie wird hier durch BGP bewirkt, ein Routing-Protokoll, das dir normalerweise mitteilt, welchen Weg du nehmen sollst, um dein Ziel-IP zu erreichen. Bei Anycast-Adressen gibt es mehrere mögliche Routen und BGP wählt die Route mit der niedrigsten Hop-Anzahl (was dem nächstgelegenen Gerät entspricht!).
Anycast wird von großen CDNs wie Cloudflare, AWS, Google Cloud und auch neueren Anbietern wie Fly.io eingesetzt. Obwohl Anycast eine super coole Technologie ist, hat sie einen großen Nachteil: Du musst dein eigenes AS und IP-Adressen besitzen. Das ist für große Unternehmen normalerweise kein Problem, aber für die meisten Startups keine Option.
Wenn du also kein eigenes AS hast, was kannst du sonst tun? Schauen wir uns DNS-basiertes Routing an.
DNS-basiertes Routing
DNS-basiertes Routing funktioniert, indem bei DNS-Abfragen verschiedene IP-Adressen basierend auf dem Standort des Nutzers zurückgegeben werden. Amazon Route53 unterstützt dies durch die EDNS0 (Extended DNS) Protokollerweiterung, speziell mit der edns-client-subnet-Erweiterung. So funktioniert es:
- Wenn ein DNS-Resolver edns-client-subnet unterstützt:
- Der Resolver sendet Route53 eine gekürzte Version der IP-Adresse des Nutzers
- Route53 verwendet diese gekürzte IP, um den Standort des Nutzers zu bestimmen
- Route53 gibt die IP-Adresse des Servers zurück, der dem tatsächlichen Standort des Nutzers am nächsten liegt
- Wenn ein DNS-Resolver edns-client-subnet nicht unterstützt:
- Route53 greift auf die IP-Adresse des DNS-Resolvers zurück
- Der Nutzer wird basierend auf dem Standort des Resolvers weitergeleitet, nicht auf seinem eigenen
- Dies kann weniger genau sein, besonders wenn ein entfernter DNS-Resolver verwendet wird
Für die meisten Nutzer bietet dies eine ausreichend gute Genauigkeit - der durchschnittliche Nutzer wird zum nächstgelegenen Server geleitet. Es gibt jedoch einige Einschränkungen, die in Christian Elsens Artikel ausführlich besprochen werden. Zusammengefasst: Die Genauigkeit ist nicht perfekt und kann manchmal Nutzer zu suboptimalen Standorten leiten. Wir sprechen hier aber nur von etwas zusätzlicher Latenz, also ist das normalerweise kein Deal-Breaker.
Die Lösung: AWS Route53 Geolocation-Routing
Wir lösen das Problem, indem wir unsere Anwendung an mehreren Hetzner-Standorten bereitstellen und Amazon Route53's Geolocation-basiertes DNS-Feature nutzen, um Nutzer zu ihrem nächstgelegenen Server zu leiten. Dieser Ansatz bietet uns:
- Geringere Latenz für alle Nutzer weltweit
- Bessere Zuverlässigkeit durch Redundanz
- Kosteneffektive globale Präsenz (ab $0,5 / Monat)
- Einfache Implementierung (Kein AS + BGP nötig)
Implementierungs-Guide
Für die Umsetzung müssen wir einige Hetzner-Server einrichten, die ein einfaches HTTP-Hello-World bereitstellen, und dann Route53 konfigurieren, um Anfragen zum nächstgelegenen Server zu leiten. Das bedeutet, du benötigst einen Domainnamen, ein Hetzner-Konto und ein AWS-Konto. Hetzner ist hier optional, du kannst natürlich genau dasselbe mit jedem anderen VPS-Anbieter machen. DigitalOcean, Linode, Vultr, OVH, AWS, etc. Sie alle machen dasselbe :)
Wenn du Hetzner ausprobieren möchtest, kannst du gerne meinen Referral-Link für 20 Euro Guthaben verwenden.
1. Hetzner-Server einrichten
Zuerst deployen wir unsere Anwendung an mehreren Hetzner-Standorten. In diesem Beispiel verwenden wir:
- Falkenstein (eu-central)
- Ashburn (us-east)
- Singapur (ap-southeast)
In diesem Beispiel erstelle ich einfach den günstigsten Server mit IPv4-Adressen. Wenn du das in Production machen würdest, würdest du wahrscheinlich stattdessen eine Floating IP verwenden (mehr dazu später).
Erstelle eine init.sh
-Datei, die wir auf jedem Server ausführen werden:
#!/bin/bash
set -e
sudo apt-get update -y
sudo apt-get install nginx -y
sudo rm -f /etc/nginx/sites-enabled/default
sudo rm -f /etc/nginx/sites-available/default
sudo bash -c 'cat > /etc/nginx/conf.d/hostname.conf <<EOF
server {
listen 0.0.0.0:80 default_server;
server_name _;
location / {
return 200 "\$hostname\n";
add_header Content-Type text/plain;
}
}
EOF'
sudo nginx -t
sudo systemctl reload nginx
echo "Server is ready"
Und dann erstelle 3 Server, 1 pro Standort. Natürlich kannst du auch weniger oder mehr machen. Wenn du hcloud nicht installiert hast, benutze einfach die Weboberfläche!
hcloud server create --image ubuntu-24.04 --name eu-central-1 --type cpx11 --location fsn1 --user-data-from-file init.sh
hcloud server create --image ubuntu-24.04 --name us-east --type cpx11 --location ash --user-data-from-file init.sh
hcloud server create --image ubuntu-24.04 --name ap-southeast --type cpx11 --location sin --user-data-from-file init.sh
Wenn wir unsere Server auflisten, sehen wir die IPv4-Adressen:
$ hcloud server list
ID NAME STATUS IPV4 IPV6 PRIVATE NET DATACENTER AGE
55560647 eu-central running 116.203.41.15 2a01:4f8:1c1b:dbf2::/64 - nbg1-dc3 1d
55560663 us-east running 178.156.130.48 2a01:4ff:f0:3c8e::/64 - ash-dc1 1d
55560674 ap-southeast running 5.223.50.246 2a01:4ff:2f0:3a21::/64 - sin-dc1 1d
Jetzt solltest du jede der IP-Adressen curlen können und etwas wie "Hello, from eu-central" zurückbekommen. (oder us-east, oder ap-southeast)
curl http://116.203.41.15
Dies sind wirklich nur 3 einfache Nginx-Server, die wir verwenden, um unser Setup zu testen. Du kannst das auch mit jedem anderen VPS-Anbieter machen. Ich mag einfach Hetzner :)
2. Route53 konfigurieren
Um Route53 zu konfigurieren, müssen wir wirklich nur eine gehostete Zone erstellen und Geolocation-Einträge für jede Region hinzufügen. Ich mache das normalerweise mit Terraform oder AWS CDK, aber in diesem Fall machen wir es einfach manuell in der Konsole.
Beginnen wir damit, eine gehostete Zone für unsere Domain zu erstellen:
- Erstelle eine gehostete Zone in Route53
Nach dem Erstellen der gehosteten Zone erhältst du ~4 Nameserver-Adressen, die du im Dashboard deines Domain-Registrars einrichten musst. Die meisten Registrare haben ein Feld "Benutzerdefinierte Nameserver", dort gehören sie hin. Das bedeutet im Grunde, dass jede DNS-Anfrage, die zu deiner Domain gehört, an die Nameserver von AWS weitergeleitet wird.
Nachdem wir die gehostete Zone erstellt und die Nameserver im Dashboard unseres Registrars eingerichtet haben, können wir Einträge erstellen. In diesem Beispiel möchte ich die Domain hetzner.example.com
verwenden. Also erstelle ich einen A-Record für jede Region mit der entsprechenden IP-Adresse, alle Records teilen sich den Record-Namen. Als Routing-Richtlinie wählst du Geolocation-Routing und dann die Region, die dem Server entspricht.
Wiederhole das für jede Region und einen zusätzlichen Eintrag für die Standardregion. Dann erhältst du etwas wie das hier:
Das war's, wir sind bereit zum Testen!
Testen
Da wir hier mit DNS arbeiten, solltest du vielleicht ein paar Minuten warten, bevor du es testest, nur um sicherzustellen, dass die DNS-Änderungen propagiert sind.
Um es zu testen, benötigst du entweder einige Freunde in verschiedenen Regionen oder ein VPN. Dann kannst du einfach den Domainnamen curlen und sehen, zu welcher IP-Adresse du weitergeleitet wirst.
$ curl http://hetzner.example.com # Anfrage aus Deutschland
eu-central-1
$ curl http://hetzner.example.com # Anfrage aus den USA
us-east
$ curl http://hetzner.example.com # Anfrage aus Hongkong
ap-southeast
Zum Zeitpunkt des Schreibens war ich in Deutschland, also wurde ich zum Falkenstein-Server weitergeleitet. Dann habe ich ein US-VPN eingeschaltet und wurde zum Ashburn-Server weitergeleitet. Dann habe ich ein Hongkong-VPN eingeschaltet und wurde zum Singapur-Server weitergeleitet. Und das war's
PS: Wenn du ein traceroute
machst, wirst du sehen, dass die Anfrage nicht durch das AWS-Netzwerk geht, sondern direkt zum ausgewählten Server.
Was ist mit den Kosten?
Die Kosten sind (offensichtlich) nur eine Kombination aus deinen Hetzner-Compute- + AWS-Route53-Kosten. Das ist eine Überschlagsrechnung, deine Ergebnisse können variieren.
Eine gehostete Zone in Route53 kostet $0,5 pro Monat. Zusätzlich hast du die Kosten für deine Abfragen. Für 1 Million Anfragen kostet dies $0,70. Wie viele Anfragen du bekommst, hängt sehr vom Typ deines Dienstes ab, wirklich der einzige Weg, um herauszufinden, was du zahlen wirst, ist, es auszuprobieren.
Da du nach Abfragen zahlst, wird die Reduzierung der Anzahl der Abfragen deine Kosten senken. Du kannst dies tun, indem du einen längeren TTL für deine DNS-Einträge verwendest, was die Zeit ist, die ein DNS-Eintrag vom DNS-Resolver zwischengespeichert wird. Durch die Erhöhung des TTL verlängerst du auch die Zeit, die es braucht, bis die Änderungen bei all deinen Nutzern ankommen. Wenn du deine IP-Adresse in Eile ändern musst (vielleicht weil du versehentlich den Server gelöscht hast?), ist es möglich, dass deine Nutzer einige Ausfallzeiten erleben. Um dem entgegenzuwirken, kannst du eine Floating IP verwenden, die dich ungefähr $3 pro Region kostet. Wenn dein Volumen sehr hoch ist (weit über 13 Millionen DNS-Abfragen), könnte es sinnvoll sein, den TTL zu erhöhen und stattdessen eine Floating IP hinzuzufügen.
Einschränkungen und Überlegungen
DNS-basiertes Routing ist nicht perfekt, hier sind einige Dinge zu beachten:
- DNS TTL: Änderungen brauchen Zeit, um sich zu verbreiten
- VPN-Nutzer: Könnten zu unerwarteten Standorten weitergeleitet werden
- Mobile Nutzer: DNS-Server der Mobilfunkanbieter können das Routing beeinflussen
- Replikation: Du musst sicherstellen, dass deine Anwendung richtig über Regionen repliziert wird, wenn Daten beteiligt sind, ist das nicht immer einfach.
Wie bereits erwähnt, hat Christian Elsen einen großartigen Artikel über die Einschränkungen des DNS-basierten Routings hier geschrieben.
Trotzdem denke ich, dass die Einschränkungen beherrschbar sind und die Vorteile es wert sind!
Fazit
Es gibt kein kostenloses Mittagessen. Global replizierte Dienste kommen mit Kosten, die über deine erhöhte Hetzner-Rechnung hinausgehen. Die meisten Anwendungen haben Daten, die sie ihren Nutzern bereitstellen müssen, und jetzt musst du diese Daten von mehreren Standorten aus bereitstellen. Das bedeutet, dass du dich mit Replikation und Konsistenz auseinandersetzen musst, oder du hast immer noch einen globalen Datenspeicher (der dann wieder dein Engpass in einer Region sein wird). Thema für einen anderen Artikel!
Die Verwendung von GeoDNS mit Hetzner bietet eine kostengünstige Möglichkeit, globale Nutzer mit niedriger Latenz zu bedienen. Obwohl es nicht so ausgereift ist wie die Anycast-Lösungen, die von großen CDNs verwendet werden, ist es ein praktischer Ansatz für den Rest von uns :)
Interessante Links
Während der Recherche für diesen Artikel habe ich einige interessante Links gefunden, die ich mit dir teilen möchte:
Ich hoffe, dir hat dieser Artikel gefallen und du hast etwas Neues gelernt! Wenn du Fragen oder Feedback hast, lass es mich wissen auf Twitter @JonasScholz19 oder unter [email protected].