Współdzielenie puli serwerów proxy między wątkami Pythona za pomocą kolejki
Użyj zsynchronizowanej kolejki i bloku finally, aby zarezerwować jeden serwer proxy dla synchronicznej operacji wątkowej, a następnie go zwrócić.
Gdy kilka wątków współdzieli małą pulę serwerów proxy, wybór losowego wpisu może dać dwóm aktywnym operacjom ten sam serwer proxy. Kolejka może przechowywać wpisy aktualnie dostępne do wypożyczenia:
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)
Zbuduj kolejkę raz, przed uruchomieniem wątków roboczych. proxy_urls zawiera pełne adresy URL punktów końcowych. Publiczni kandydaci są dostępni na liście darmowych serwerów proxy; użyj protokołu i formatu URL obsługiwanego przez fetch_one. Istniejąca synchroniczna funkcja fetch_one musi zakończyć operację sieciową i zamknąć każdą odpowiedź przed powrotem. W przeciwnym razie wypożyczenie zakończyłoby się, gdy połączenie nadal używa tego serwera proxy.
Queue.get atomowo usuwa jeden dostępny wpis. Wyczerpana pula czeka, zamiast wielokrotnie skanować współdzielone flagi. Jeśli w ciągu pięciu sekund nie pojawi się żaden wpis, queue.Empty dociera do wywołującego; wybierz politykę ponawiania, błędu lub anulowania aplikacji dla tego wyniku.
Blok finally zwraca pozyskany wpis po sukcesie lub wyjątku. Nie ogłasza, że nieudany punkt końcowy jest zdrowy. Zasady kwarantanny, wymiany i schładzania wymagają jawnej ścieżki, zamiast po cichu odrzucać każdy serwer proxy, który napotka tymczasowy błąd.
Usuwanie duplikatów identycznych ciągów URL zapobiega podwójnym wpisom w kolejce. Różne adresy URL nadal mogą wskazywać ten sam fizyczny serwer proxy lub wyjście; grupuj je świadomie, jeśli wyłączność ma dotyczyć tego współdzielonego zasobu. Kolejka koordynuje wątki w tym procesie, a nie procesy robocze na innych maszynach.