Eine Multi-Region-Architektur brauchen Sie genau dann, wenn Ihre Zielseiten über mehrere Kontinente verteilt sind oder wenn harte Verfügbarkeitszusagen gelten. Sitzen die CAPTCHA-Worker näher an den Zielstandorten, sinkt die Roundtrip-Zeit zur API, und ein regionaler Ausfall legt nicht die gesamte Pipeline lahm.
Der Aufwand lohnt sich aber nur, wenn Geografie wirklich Teil des Problems ist. Liegen Ihre Ziele in einer einzigen Region und bleibt die Last moderat, erhöht Multi-Region zunächst vor allem die Betriebs- und Monitoring-Komplexität.
Wann sich Multi-Region wirklich lohnt
| Frage | Antwort „ja" | Antwort „nein" |
|---|---|---|
| Zielseiten auf mehreren Kontinenten? | Regionale Verteilung ist plausibel | Eine Region genügt meist |
| Harte Uptime- oder Failover-Vorgaben? | Multi-Region lohnt sich | Halten Sie das Design schlank |
| Müssen Daten regional bleiben (DSGVO)? | Regionale Trennung einplanen | Zusätzliche Regionen oft unnötig |
| Ist das Volumen noch gering? | Erst eine Region stabilisieren und messen | Nicht vorschnell ausbauen |
Architekturüberblick
[Task Router]
(Route53 / Load Balancer)
↙ ↓ ↘
[US-East] [EU-West] [AP-Southeast]
Workers Workers Workers
↓ ↓ ↓
[CaptchaAI API] ← shared API key
↓ ↓ ↓
[Central DB / Queue]
(Results aggregation)
Jede Region betreibt eigene, unabhängige Worker. Alle nutzen denselben CaptchaAI-API-Schlüssel und schreiben ihre Ergebnisse in einen zentralen Speicher. Ein Task-Router verteilt Aufgaben nach Zielgeografie.
Einzelne Region oder Multi-Region im direkten Vergleich
| Situation | Einzelne Region | Multi-Region |
|---|---|---|
| Zielseiten in einem Land | Ausreichend | Überdimensioniert |
| Globale Zielseiten | 100–300 ms zusätzliche Latenz | Lokale Latenz je Region |
| 99,9 % Verfügbarkeit gefordert | Schwer einzuhalten | Natürliche Redundanz |
| Regulatorische Datenresidenz | Nicht erfüllbar | Lokale Verarbeitung |
| < 1.000 Aufgaben/Stunde | Ausreichend | Unnötige Komplexität |
| > 10.000 Aufgaben/Stunde | Skalierungsgrenzen | Verteilt die Last |
Für DACH-Teams ist die mittlere Zeile oft der Auslöser: Ein Worker in eu-central-1 (Frankfurt) auf Hetzner oder IONOS hält die Latenz für .de-Ziele niedrig.
DSGVO und Datenverarbeitung im DACH-Raum
Sobald CAPTCHA-Worker mit personenbezogenen Daten in Berührung kommen – und dazu zählen bereits IP-Adressen –, wird die Region zur Compliance-Frage. Ein Worker in eu-central-1 verarbeitet Anfragen für .de-Ziele innerhalb der EU, was die Argumentation gegenüber der eigenen Datenschutzabteilung deutlich vereinfacht.
Multi-Region ist dabei kein Freibrief. Die regionale Trennung hilft nur, wenn der gesamte Datenfluss dazu passt:
- Task-Router und zentrale Ergebnis-Queue ebenfalls in der EU-Region betreiben, nicht nur die Worker.
- Logs und Monitoring-Daten mit IP-Bezug in derselben Region halten.
- Die Rechtsgrundlage für die Verarbeitung eigenständig prüfen – CaptchaAI trifft dazu keine Zusagen.
Hinweis: Regionale Verarbeitung ist eine technische Maßnahme, kein Ersatz für eine datenschutzrechtliche Bewertung Ihres konkreten Workflows.
Regionale Worker bereitstellen
Python-Worker (regionsbewusst)
import os
import time
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
REGION = os.environ.get("WORKER_REGION", "us-east-1")
RESULT_QUEUE_URL = os.environ["RESULT_QUEUE_URL"]
def solve_captcha(task):
"""Solve CAPTCHA and tag with region metadata."""
start = time.time()
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": task["method"],
"googlekey": task["sitekey"],
"pageurl": task["pageurl"],
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {
"task_id": task["task_id"],
"error": data.get("request"),
"region": REGION
}
captcha_id = data["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": captcha_id, "json": 1
}).json()
if result.get("status") == 1:
return {
"task_id": task["task_id"],
"solution": result["request"],
"region": REGION,
"duration": time.time() - start,
"api_latency_ms": round((time.time() - start) * 1000)
}
if result.get("request") != "CAPCHA_NOT_READY":
return {
"task_id": task["task_id"],
"error": result.get("request"),
"region": REGION
}
return {"task_id": task["task_id"], "error": "TIMEOUT", "region": REGION}
Jeder Worker liest seine Region aus WORKER_REGION und hängt sie an jedes Ergebnis. So lassen sich Lösungszeit und Fehlerquote sauber pro Region auswerten.
Task-Router
Leiten Sie jede Aufgabe an die Region weiter, die dem Zielstandort am nächsten liegt:
from urllib.parse import urlparse
# Region mapping by target site TLD/domain
REGION_MAP = {
".co.uk": "eu-west-1",
".de": "eu-central-1",
".fr": "eu-west-3",
".jp": "ap-northeast-1",
".com.au": "ap-southeast-2",
".com": "us-east-1", # Default
}
REGION_QUEUES = {
"us-east-1": "sqs://captcha-tasks-us-east",
"eu-west-1": "sqs://captcha-tasks-eu-west",
"ap-southeast-1": "sqs://captcha-tasks-ap-southeast",
}
def route_task(task):
"""Route task to the closest regional queue."""
domain = urlparse(task["pageurl"]).netloc
target_region = "us-east-1" # Default
for suffix, region in REGION_MAP.items():
if domain.endswith(suffix):
target_region = region
break
queue = REGION_QUEUES.get(target_region, REGION_QUEUES["us-east-1"])
send_to_queue(queue, task)
return target_region
Die Zuordnung über die Top-Level-Domain ist bewusst simpel: .de landet in Frankfurt, alles Übrige fällt auf die US-Standardregion zurück.
Infrastruktur mit Terraform und Docker
Terraform-Skelett
# Define regions
variable "regions" {
default = ["us-east-1", "eu-west-1", "ap-southeast-1"]
}
# Deploy worker fleet per region
module "captcha_workers" {
for_each = toset(var.regions)
source = "./modules/captcha-worker"
region = each.key
worker_count = var.workers_per_region
api_key_secret_arn = aws_secretsmanager_secret.captchaai_key.arn
task_queue_arn = aws_sqs_queue.tasks[each.key].arn
result_queue_arn = aws_sqs_queue.results.arn
}
# SQS queue per region for task intake
resource "aws_sqs_queue" "tasks" {
for_each = toset(var.regions)
name = "captcha-tasks-${each.key}"
}
# Central result queue
resource "aws_sqs_queue" "results" {
name = "captcha-results-central"
}
Eine Warteschlange pro Region nimmt Aufgaben entgegen, eine zentrale Warteschlange sammelt die Ergebnisse ein; der API-Schlüssel liegt im Secrets Manager.
Docker Compose (lokale Simulation mehrerer Regionen)
version: "3.8"
services:
worker-us:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=us-east-1
- TASK_QUEUE=redis://redis:6379/0
depends_on:
- redis
worker-eu:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=eu-west-1
- TASK_QUEUE=redis://redis:6379/1
worker-ap:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=ap-southeast-1
- TASK_QUEUE=redis://redis:6379/2
redis:
image: redis:7-alpine
So testen Sie Routing und Failover lokal, bevor echte Regionen Kosten verursachen.
Health-Monitoring pro Region
JavaScript
const axios = require("axios");
const REGIONS = ["us-east-1", "eu-west-1", "ap-southeast-1"];
async function checkRegionHealth() {
const health = {};
for (const region of REGIONS) {
const endpoint = `https://${region}.workers.example.com/health`;
try {
const start = Date.now();
const resp = await axios.get(endpoint, { timeout: 5000 });
health[region] = {
status: "healthy",
latencyMs: Date.now() - start,
activeWorkers: resp.data.activeWorkers,
queueDepth: resp.data.queueDepth,
};
} catch (err) {
health[region] = { status: "unhealthy", error: err.message };
}
}
return health;
}
// Periodic health check
setInterval(async () => {
const health = await checkRegionHealth();
console.table(health);
}, 60000);
Der Health-Check fragt jede Region im Minutentakt ab und erfasst Latenz, aktive Worker und Warteschlangentiefe.
Failover-Strategie
Fällt eine Region aus, verteilen Sie ihre Aufgaben auf die verbleibenden:
def failover_check(region_health):
"""Redirect tasks from unhealthy regions."""
healthy_regions = [
r for r, h in region_health.items()
if h["status"] == "healthy"
]
if not healthy_regions:
raise RuntimeError("All regions unhealthy")
redirects = {}
for region, health in region_health.items():
if health["status"] == "unhealthy":
# Pick the healthy region with lowest queue depth
target = min(
healthy_regions,
key=lambda r: region_health[r].get("queue_depth", 0)
)
redirects[region] = target
print(f"Failover: {region} → {target}")
return redirects
Die Logik wählt für jede gestörte Region die gesunde Region mit der geringsten Warteschlangentiefe. Sind alle Regionen gestört, bricht die Funktion bewusst mit einem Fehler ab, statt Aufgaben ins Leere zu routen.
Kostenüberlegungen
| Komponente | Kostenfaktor | Optimierung |
|---|---|---|
| Worker-Instanzen | Compute je Region | Im Leerlauf automatisch auf 0 skalieren |
| Regionsübergreifender Datentransfer | 0,02 $/GB zwischen Regionen | Ergebnis-Payload klein halten |
| SQS-Warteschlangen | Preis pro Anfrage | Nachrichten bündeln, wo möglich |
| CaptchaAI-API | Gleiche Kosten unabhängig von der Region | Kein Aufpreis für Multi-Region |
CaptchaAI rechnet unabhängig vom Standort des Workers dieselben Tarife ab – die Mehrkosten entstehen ausschließlich in der Infrastruktur. Da CaptchaAI Thread-basiert abrechnet (unbegrenzte Lösungen pro Thread, ab BASIC mit 15 $/Monat und 5 Threads), teilen sich alle Regionen dasselbe Thread-Kontingent.
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| Eine Region ist dauerhaft langsamer | Distanz zu den CaptchaAI-Servern | Basislatenz vergleichen – kann erwartbar sein |
| Routing schickt alles in eine Region | Domainbasierte Regeln zu grob | Feinere Regeln nach Hostname ergänzen |
| Failover greift nicht | Health-Endpunkt antwortet nicht | Health-Pfad von der Worker-Logik trennen |
| Guthaben sinkt schneller als erwartet | Alle Regionen teilen einen Schlüssel | Erwartbar – Gesamtverbrauch zentral überwachen |
Schrittweiser Aufbau ohne Big Bang
Eine Multi-Region-Architektur muss nicht in einem Schritt entstehen. Bewährt hat sich ein schrittweises Vorgehen:
- Eine Region sauber stabilisieren und Basislatenz sowie Erfolgsquote messen.
- Eine zweite Region auf einem anderen Kontinent ergänzen und das Failover zunächst im Docker-Compose-Setup lokal testen.
- Das TLD-basierte Routing aktivieren und den Anteil der Aufgaben pro Region beobachten.
- Erst danach eine dritte Region ergänzen, wenn Latenz oder Verfügbarkeit es rechtfertigen.
So bleibt jeder Schritt messbar, und die Betriebskomplexität wächst nur dann, wenn sie einen konkreten Nutzen bringt.
Häufige Fragen
Wie viele Regionen brauche ich für Hochverfügbarkeit?
Zwei Regionen in unterschiedlichen Räumen (z. B. USA + EU) genügen für eine solide Grundabsicherung; erst ein dritter Standort in Asien deckt weltweite Verfügbarkeit ab.
Wie route ich Aufgaben für .de-Ziele nach Frankfurt?
Über die TLD: Im REGION_MAP-Dictionary zeigt .de auf eu-central-1. Der Router prüft die Domain der pageurl und legt die Aufgabe in die passende regionale Warteschlange.
Ist ein Multi-Region-Setup automatisch DSGVO-konform?
Nein, das hängt von Ihrem Datenfluss ab, nicht von CaptchaAI. Regionale Trennung kann helfen, personenbezogene Daten wie IP-Adressen lokal zu verarbeiten, ersetzt aber keine eigene Prüfung der Rechtsgrundlage.
Wie überwache ich den Thread-Verbrauch über alle Regionen hinweg?
Zentral, nicht pro Region. Da alle Regionen denselben API-Schlüssel und damit dasselbe Thread-Kontingent teilen, zählt nur der aggregierte Verbrauch. Erfassen Sie die Lösungen über die Region-Metadaten aus jedem Worker und summieren Sie sie im zentralen Speicher.
Verwandte Leitfäden
- Hochverfügbare CAPTCHA-Lösung mit Failover
- Worker für CAPTCHA-Lösung automatisch skalieren
- CAPTCHA-Lösungsleistung nach Region