Einen Proxy-Pool zwischen Python-Threads mit einer Queue teilen
Verwenden Sie eine synchronisierte Queue und einen finally-Block, um einen Proxy für eine synchrone Thread-Operation zu reservieren und ihn danach zurückzugeben.
Wenn mehrere Threads einen kleinen Proxy-Pool teilen, kann die Auswahl eines zufälligen Eintrags zwei aktiven Vorgängen denselben Proxy geben. Eine Queue kann die derzeit ausleihbaren Einträge halten:
from contextlib import contextmanager
from queue import Queue
available = Queue()
for endpoint in dict.fromkeys(proxy_urls):
available.put(endpoint)
@contextmanager
def borrow_proxy():
endpoint = available.get(timeout=5)
try:
yield endpoint
finally:
available.put(endpoint)
def process_url(url):
with borrow_proxy() as endpoint:
return fetch_one(url, endpoint)
Erstellen Sie die Queue einmal, bevor die Worker-Threads starten. proxy_urls enthält vollständige Endpunkt-URLs. Öffentliche Kandidaten finden Sie in der Liste kostenloser Proxys; verwenden Sie das Protokoll und URL-Format, das fetch_one unterstützt. Die vorhandene synchrone Funktion fetch_one muss ihren Netzwerkvorgang abschließen und jede Antwort schließen, bevor sie zurückkehrt. Andernfalls endet die Ausleihe, während die Verbindung diesen Proxy noch nutzt.
Queue.get entnimmt einen verfügbaren Eintrag atomar. Ein erschöpfter Pool wartet, statt wiederholt gemeinsame Flags zu prüfen. Kommt innerhalb von fünf Sekunden kein Eintrag, erreicht queue.Empty den Aufrufer; wählen Sie für dieses Ergebnis die Wiederholungs-, Fehler- oder Abbruchrichtlinie der Anwendung.
Der finally-Block gibt einen entnommenen Eintrag nach Erfolg oder einer Ausnahme zurück. Er erklärt einen fehlgeschlagenen Endpunkt nicht für gesund. Quarantäne-, Ersatz- und Abklingrichtlinien brauchen einen ausdrücklichen Pfad, statt jeden Proxy stillschweigend zu verwerfen, der einen temporären Fehler sieht.
Das Entfernen doppelter identischer URL-Zeichenketten verhindert doppelte Queue-Einträge. Verschiedene URLs können weiterhin auf denselben physischen Proxy oder Ausgang verweisen; gruppieren Sie sie bewusst, wenn Exklusivität für diese gemeinsame Ressource gelten soll. Die Queue koordiniert Threads in diesem Prozess, nicht Worker auf anderen Maschinen.