Geben Sie jedem aiohttp-Proxy ein eigenes Parallelitätsbudget
Begrenzen Sie laufende Arbeit pro ausgewähltem Proxy, während die Verbindungspool-Grenzen von aiohttp und die Antwortbereinigung erhalten bleiben.
Ein Proxy-Pool kann Endpunkte mit sehr unterschiedlicher Kapazität enthalten. Fünfzig Vorgänge in der gesamten Anwendung zuzulassen, hindert neunundvierzig davon nicht daran, denselben Proxy zu wählen.
Wenn die Richtlinie „höchstens vier laufende Vorgänge über jeden ausgewählten Proxy“ lautet, drücken Sie diese Richtlinie direkt aus. Halten Sie ein Semaphor für jede Proxy-Identität bereit und erwerben Sie es um die Arbeit herum, die die Kapazität des Proxys verbraucht.
limits = {proxy: asyncio.Semaphore(4) for proxy in proxy_urls}
async def fetch(session, proxy, url):
async with limits[proxy]:
async with session.get(url, proxy=proxy) as response:
return await response.read()Diese Skizze setzt voraus, dass asyncio importiert und die Proxy-URLs validiert wurden. Für öffentliche Anfragen auf einer zulässigen öffentlichen Proxy-Route liefert die HTTP-Proxy-Liste Kandidaten für die Proxy-URLs von aiohttp. Eine echte Anwendung sollte außerdem ihr eigenes Anforderungs-Timeout setzen und entscheiden, wie viele Antwortdaten sie benötigt. Eine große Datei vollständig in den Speicher zu lesen, ist eine separate Ressourcenentscheidung.
Behalten Sie die Erlaubnis für den teuren Teil
Das Semaphor freizugeben, sobald die Antwortheader eintreffen, kann die beabsichtigte Begrenzung zunichtemachen. Ein gestreamter Body kann die Verbindung noch lange danach nutzen. Behalten Sie die Erlaubnis, bis der Body verbraucht oder die Antwort gemäß dem Arbeitsablauf der Anwendung geschlossen wurde.
Die verschachtelten Kontextmanager machen die Bereinigung sichtbar, wenn eine Ausnahme oder ein Abbruch den Vorgang verlässt. Vermeiden Sie manuelles Erwerben und Freigeben nur am Ende einer erfolgreichen Funktion.
Verbindungsgrenzen beantworten eine andere Frage
Die Connector-Grenzen von aiohttp begrenzen Verbindungen nach den dokumentierten Regeln des Connectors. Sie bleiben neben einem Anwendungssemaphor nützlich. Eine Verbindungsgrenze pro Ziel drückt allein durch ihren Namen kein Budget aus, das von allen einem Proxy zugewiesenen Zielen geteilt wird.
Unterscheiden Sie außerdem Parallelität von Anforderungsrate. Vier langlebige Anforderungen und vier sehr kurze Anforderungen nutzen dieselbe Parallelitätszuteilung, erzeugen aber unterschiedliche Anforderungen-pro-Sekunde-Raten. Ein Dienst mit einer Ratenrichtlinie kann eine Taktung oder einen separaten Ratenbegrenzer benötigen.
Wählen Sie eine stabile, nicht geheime Proxy-Kennung für Protokolle und Metriken. Wenn zwei URLs mit Anmeldedaten auf denselben Kapazitätspool verweisen, entscheiden Sie, ob sie ein Budget teilen sollen. Umgekehrt können verschiedene Ports oder Konten separate Grenzen darstellen, wenn der Betreiber sie so dokumentiert.
Wenn der Durchsatz sinkt, prüfen Sie, wo Arbeit wartet: Ihr Semaphor, der Connector, der Aufbau der Proxy-Verbindung oder das Lesen der Antwort. Alle Grenzen gleichzeitig anzuheben, macht diese Unterscheidung schwieriger und kann die Warteschlange in einen Proxy verschieben, den Sie nicht kontrollieren.