Wissen

Residential-Proxy-Lastverteilung: Rotations-, Nebenläufigkeits- und Retry-Architektur

Mit einem Gateway balanciert sich der Pool selbst. Die Architektur, die zählt, ist Ihre: Rotationseinheiten, Nebenläufigkeit pro Host, und eine Retry-Schicht, die Blocks nicht verstärkt.

Chris Collins

Chris Collins

17. Juli 2026 · 9 Min. Lesezeit

“Proxy-Lastverteilung” ist ein Begriff, der heute etwas ganz anderes bedeutet als früher. Im alten Modell kauften Sie eine IP-Liste und bauten einen Rotator: eine IP wählen, ihre Gesundheit verfolgen, sie herausnehmen, wenn sie stirbt, sie später wieder hineinlegen. Teams schreiben diese Middleware immer noch aus Gewohnheit, und auf einem modernen Gateway ist sie größtenteils toter Code.

Auf einem Residential-Proxy-Gateway balanciert sich der Pool selbst. Ein Endpunkt, und der Anbieter weist serverseitig pro Anfrage oder pro Session einen Exit aus Millionen von IPs zu. Sie balancieren keine IPs. Was Sie sehr wohl architektieren, ist die Schicht darüber: wie Arbeit auf Identitäten abgebildet wird, wie viel Nebenläufigkeit ein Ziel toleriert, und was passiert, wenn eine Anfrage fehlschlägt. Treffen Sie diese drei richtig, skaliert das System; treffen Sie sie falsch, rettet Sie kein Maß an Proxy-Qualität.

Dies ist ein Deep-Dive zu diesen drei Schichten, für Teams, die Erfassungs-Pipelines in Produktion betreiben.

Was das Gateway tut, und wo Ihre Architektur beginnt

Es lohnt sich, bei der Aufteilung präzise zu sein, denn sie bestimmt, was Sie bauen sollten und was nicht:

Das Gateway übernimmt: die Exit-IP-Auswahl aus dem Pool, Geo-Matching, die Gesundheit einzelner IPs, und die Rotationsmechanik. Sie drücken Absicht über den Benutzernamen aus (country, city, sid, ttl), und es löst das zu einem Exit auf.

Sie übernehmen: die Identitätseinheit (was eine eigene IP bekommt, und wie lange), Nebenläufigkeitskontrolle (wie hart Sie jedes Ziel drücken), Retry-Policy (was bei Fehlschlägen passiert), und Observability.

Der häufigste Architekturfehler ist, eine Proxy-Rotator-Schicht zu bauen, die das Gateway dupliziert. Wenn Sie sich dabei ertappen, eine IP-Gesundheitstabelle zu pflegen, hören Sie auf, das ist die Aufgabe des Anbieters, und Ihre Version hat einen schlechteren Blick auf den Pool als seine. Ihre Arbeit beginnt auf der Ebene der Anfrage-Policy.

Schicht 1: Rotationsarchitektur, die Identitätseinheit wählen

Das ist die Designentscheidung, an der alles andere hängt. Die Frage ist nicht “wie oft sollte ich rotieren?”, sondern “was ist eine Identität, und welche Arbeit gehört zu ihr?”

Die zwei Primitive:

  • Rotation pro Anfrage (sid weglassen): jede Anfrage bekommt eine frische Exit-IP. Maximale IP-Vielfalt, null Verbindungs-Wiederverwendung, ideal für große Mengen unabhängiger Abrufe, bei denen keine Anfrage von der letzten abhängt.
  • Sticky Session (sid + ttl): alle Anfragen mit dieser Session-ID teilen eine Exit-IP, bis die TTL abläuft. Nötig, wenn ein Flow wie ein Nutzer aussehen muss, und es ist auch das, was gepoolte Verbindungen wiederverwendbar macht (siehe Sticky vs Rotierend).

Die Designregel: rotieren Sie an der Grenze einer logischen Arbeitseinheit, nicht willkürlich. Eine Arbeitseinheit ist, was intern konsistent sein muss, die paginierten Rezensionen eines Produkts, ein Suchflow, die Session eines Kontos. Bilden Sie es sauber ab:

ein Worker = eine Arbeitseinheit = eine sid = eine Exit-IP (für ihre TTL)

Leiten Sie die Session-ID aus der Arbeitseinheit ab statt zufällig, damit Verhalten reproduzierbar ist und Sie bewusst entscheiden können, ob ein Retry die Identität behält oder wechselt:

def session_id(job_id: str, attempt: int = 0) -> str:
# Gleicher Job → gleiche Identität. `attempt` erhöhen, um bewusst eine neue IP zu bekommen.
return f"{job_id}-a{attempt}"
def proxy_for(job_id, attempt=0, country="us", ttl=600):
sid = session_id(job_id, attempt)
user = f"{USER}-country-{country}-sid-{sid}-ttl-{ttl}"
url = f"http://{user}:{PASS}@p.shifter.io:443"
return {"http": url, "https": url}

Dieser eine attempt-Parameter leistet echte Architekturarbeit: er macht “Retry auf einer anderen Identität” zu einer erstklassigen, absichtlichen Operation statt zu einem Zufall.

Schicht 2: Nebenläufigkeitsarchitektur, und warum sie pro Host ist

Die Beschränkung der Nebenläufigkeit ist fast nie Ihr Proxy-Tarif (nebenläufige Verbindungen sind typischerweise nicht das Limit). Es ist das, was das Ziel toleriert. Was bedeutet, dass ein einzelnes globales Nebenläufigkeitslimit die falsche Form hat: es lässt ein permissives Ziel ein fragiles aushungern, und lässt ein fragiles Ihre ganze Pipeline drosseln.

Limitieren Sie pro Host, nicht global:

import asyncio
from collections import defaultdict
# Ein Semaphor pro Zielhost, abgestimmt auf das, was dieser Host toleriert
_limits = {"tough-site.example": 4, "open-site.example": 32}
_sems = defaultdict(lambda: asyncio.Semaphore(8)) # sinnvoller Default
for host, n in _limits.items():
_sems[host] = asyncio.Semaphore(n)
async def fetch(client, url, host):
async with _sems[host]: # Backpressure pro Host angewandt
return await client.get(url, timeout=30)

Zwei Eigenschaften, die das bringt. Isolation: ein langsames oder feindliches Ziel kann nicht alle Worker verbrauchen. Abstimmbarkeit: Sie können die Nebenläufigkeit bei Zielen erhöhen, denen es egal ist, und bei dem, das blockiert, unabhängig herunterdrehen.

Und widerstehen Sie dem Drang, die Zahlen hochzudrehen. Jenseits der Toleranz eines Ziels kauft zusätzliche Parallelität keinen Durchsatz, sie kauft Blocks, und Blocks kosten Sie in Retries mehr, als die Nebenläufigkeit je gewann (Latenz senken behandelt diesen Handel).

Schicht 3: Retry-Architektur, der entscheidende Teil

Die meisten Pipelines scheitern hier. Ein naives for attempt in range(3): retry() macht aus einem schlechten Nachmittag einen Retry-Sturm, der Blocks verstärkt und Bandbreite verbrennt. Eine echte Retry-Schicht tut vier Dinge.

1. Klassifizieren vor dem Retry. Nicht alle Fehler sind gleich, und die Antwort ist für jeden anders:

FehlerBeispielRichtige Antwort
TransportTimeout, Connection ResetRetry, gleiche Identität ist okay
Rate-Limit429Hart zurückfahren, den ganzen Host verlangsamen
Block403, CAPTCHA, Soft Block mit 200Retry auf neuer Identität, IP nicht wiederverwenden
Permanent404, 400Kein Retry, protokollieren und weiter

Beachten Sie den Soft Block: ein 200 mit einer CAPTCHA-Seite ist ein Fehler. Wenn Sie nur nach Statuscode klassifizieren, zählen Sie Blocks als Erfolge, und Ihre Pipeline füllt sich still mit Müll (warum Scraper blockiert werden).

2. Backoff mit Jitter. Exponentielles Backoff ohne Jitter synchronisiert Ihre Worker zu einer Herde, die das Ziel in Wellen trifft. Fügen Sie immer Zufall hinzu.

3. Identität bei Blocks wechseln. Einen Block auf derselben Sticky-IP zu wiederholen, heißt, um dieselbe Ablehnung zu bitten. Erhöhen Sie den Versuchszähler, damit sich die Session-ID ändert und das Gateway Ihnen einen anderen Exit gibt.

import random, asyncio
async def fetch_with_policy(client, url, job_id, host, max_attempts=4):
for attempt in range(max_attempts):
proxies = proxy_for(job_id, attempt=attempt) # neue Identität pro Versuch
try:
r = await client.get(url, proxies=proxies, timeout=30)
kind = classify(r) # ok | ratelimit | block | permanent
if kind == "ok":
return r
if kind == "permanent":
return None # keine Versuche verschwenden
if kind == "ratelimit":
await slow_down(host) # das Tempo des Hosts weiten
except (asyncio.TimeoutError, ConnectionError):
pass # Transport: Retry
backoff = (2 ** attempt) + random.uniform(0, 1) # Jitter, immer
await asyncio.sleep(backoff)
await dead_letter(job_id, url) # parken, die Pipeline nicht blockieren
return None

4. Elegant aufgeben. Nach N Versuchen parken Sie das Item in einer Dead-Letter-Queue und machen weiter. Unbegrenzte Retries retten keinen Job; sie verwandeln einen Fehlschlag in anhaltende Last gegen ein Ziel, das Sie bereits abweist.

Zwei weitere Muster, die sich im Maßstab lohnen: ein Circuit Breaker pro Host (bricht die Erfolgsrate ein, hören Sie eine Weile auf zu senden, statt zu mahlen), und idempotente Arbeitseinheiten, damit ein Retry immer sicher ausführbar ist.

Die Referenzform

Zusammengesetzt sieht die Pipeline so aus:

Arbeitsqueue
Limiter pro Host (Semaphor + Tempo)
Worker → Session-ID (sid) → Gateway → Ziel
Antwort klassifizieren
├── ok → Inhalt validieren → ausgeben
├── ratelimit → Host verlangsamen → Backoff + requeue
├── Block → neue Identität → Backoff + requeue
└── permanent → protokollieren, verwerfen
↓ (nach N Versuchen)
Dead-Letter-Queue

Jeder Pfeil ist eine Entscheidung, die Sie sonst implizit und schlecht träfen. Explizit gemacht, degradiert das System elegant, statt zu kollabieren.

Observability: blind lässt sich das nicht betreiben

Instrumentieren Sie mindestens: Erfolgsrate pro Host (mit Inhaltsvalidierung, nicht Statuscodes), p50/p95-Latenz, Retry-Rate und Fehlertyp-Aufschlüsselung, und Bytes pro erfolgreichem Datensatz. Diese vier sagen Ihnen, wo zu handeln ist, eine steigende Retry-Rate bei einem Host heißt, dessen Nebenläufigkeit zu straffen; steigende Bytes-pro-Datensatz heißen, Sie ziehen Payload, die Sie nicht parsen (Bandbreitenkosten senken). Die Messmethoden stehen in wie man Proxy-Geschwindigkeit, Erfolgsrate und Standortgenauigkeit testet.

Zu vermeidende Anti-Muster

  • Einen IP-Rotator auf einem Gateway bauen. Redundant, und schlechter informiert als das Balancing des Anbieters.
  • Ein globales Nebenläufigkeitslimit. Koppelt unabhängige Ziele; limitieren Sie pro Host.
  • Blocks auf derselben Sticky-IP wiederholen. Gleiche IP, gleiche Antwort.
  • Backoff ohne Jitter. Synchronisiert Worker zu Wellen.
  • Unbegrenzte Retries. Verstärken Blocks, verbrennen Bandbreite, verzögern nur das Unvermeidliche.
  • 200 als Erfolg behandeln. Soft Blocks sind 200er; validieren Sie den Inhalt, sonst verrotten Ihre Daten still.
  • Mitten im Flow rotieren. Ein IP-Wechsel innerhalb einer mehrstufigen Session ist ein Erkennungssignal, rotieren Sie an Einheitsgrenzen.

FAQ

Muss ich Proxy-Lastverteilung selbst bauen? Nicht auf IP-Ebene. Ein Gateway weist Exits serverseitig aus dem Pool zu, also sind ein IP-Rotator oder eine Gesundheitstabelle auf Ihrer Seite redundant. Architektieren Sie die Schicht darüber: Identitätseinheiten, Nebenläufigkeit pro Host, und Retry-Policy.

Wie viele nebenläufige Anfragen sollte ich fahren? Es hängt vom Ziel ab, nicht von Ihrem Tarif. Setzen Sie ein Limit pro Host basierend darauf, was dieser Host toleriert, und stimmen Sie jedes unabhängig ab. Jenseits dieses Punkts produziert mehr Parallelität Blocks, keinen Durchsatz.

Sollte ein Retry dieselbe IP oder eine neue nutzen? Hängt vom Fehler ab. Transportfehler (Timeouts) können auf derselben Identität wiederholt werden. Blocks und CAPTCHAs sollten auf einer neuen Identität wiederholt werden, mit geänderter Session-ID, da die IP das ist, was abgewiesen wurde.

Wie verhindere ich, dass Retries das Blockieren verschlimmern? Fehler klassifizieren, exponentiell mit Jitter zurückfahren, Versuche begrenzen, Aussichtsloses ins Dead-Letter schicken, und einen Circuit Breaker pro Host ergänzen. Unbegrenzte, unklassifizierte Retries sind, wie aus einem kleinen Block-Problem ein großes wird.

Was sollte ich in einer Proxy-Pipeline überwachen? Erfolgsrate pro Host (mit Inhaltsvalidierung), p50/p95-Latenz, Retry-Rate mit Fehlertyp-Aufschlüsselung, und Bytes pro erfolgreichem Datensatz. Diese vier bringen nahezu jedes lohnende Problem ans Licht.

Fazit

Auf einem Gateway ist die Lastverteilung des Pools nicht Ihr Problem, und so zu tun, als wäre sie es, führt Teams dazu, das Falsche zu bauen. Die Architektur, die tatsächlich bestimmt, ob eine Erfassungs-Pipeline skaliert, lebt in drei Entscheidungen: was eine Identität ausmacht und welche Arbeit zu ihr gehört, wie viel Nebenläufigkeit jedes einzelne Ziel toleriert, und wie Fehler klassifiziert, zurückgefahren, neu identifiziert und schließlich aufgegeben werden. Treffen Sie diese richtig, instrumentieren Sie sie, und die Pipeline degradiert unter Druck elegant, statt umzufallen.

Das Gateway erledigt den Rest. Wenn Sie das aufbauen, gibt Ihnen das Residential-Gateway Rotation und Sticky Sessions über den Benutzernamen, sodass Ihre Architektur in Ihrem Code bleibt, nicht in einer Proxy-Management-Schicht, und die Poolqualität bestimmt, wie oft dieser Retry-Pfad überhaupt beansprucht wird (IP-Reputation). Für Überlegungen im großen Maßstab siehe das beste Residential-Proxy-Netzwerk für Scraping im großen Maßstab, und die Preisseite hat die Pro-GB-Tarife, um das Design gegen Ihren eigenen Workload zu testen.

Bereit, loszulegen?

Testen Sie Shifters Residential-Proxys, 205M+ IPs, 195+ Länder, ab $0.75/GB.

Jetzt starten