Дайте каждому прокси aiohttp собственный бюджет параллельности
Ограничьте текущую работу на каждом выбранном прокси, сохраняя лимиты пула соединений aiohttp и очистку ответов.
Пул прокси может содержать конечные точки с очень разной пропускной способностью. Разрешение пятидесяти операций во всём приложении не мешает сорока девяти из них выбрать один и тот же прокси.
Если правило — «не более четырёх текущих операций через каждый выбранный прокси», выразите это правило напрямую. Держите семафор для каждой идентичности прокси и захватывайте его вокруг работы, которая расходует его пропускную способность.
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()Этот набросок предполагает, что asyncio уже импортирован, а URL прокси проверены. Для публичных запросов на разрешённом публичном маршруте прокси список HTTP-прокси предоставляет кандидатов для URL прокси aiohttp. Настоящему приложению также следует задать собственный тайм-аут запроса и решить, сколько данных ответа ему нужно. Чтение большого файла целиком в память — отдельное решение о ресурсах.
Сохраняйте разрешение для дорогой части
Освобождение семафора сразу при получении заголовков ответа может свести на нет задуманное ограничение. Потоковое тело может продолжать использовать соединение ещё долго. Сохраняйте разрешение, пока тело не израсходовано или ответ не закрыт в соответствии с рабочим процессом приложения.
Вложенные контекстные менеджеры делают очистку видимой, когда исключение или отмена покидают операцию. Избегайте ручного захвата и освобождения только в конце успешной функции.
Лимиты соединений отвечают на другой вопрос
Лимиты коннектора aiohttp ограничивают соединения по документированным правилам коннектора. Они остаются полезными рядом с семафором приложения. Лимит соединений на пункт назначения не выражает, только по своему названию, бюджет, общий для всех пунктов назначения, назначенных одному прокси.
Различайте также параллельность и частоту запросов. Четыре долгоживущих запроса и четыре очень коротких запроса используют одну и ту же квоту параллельности, но дают разную частоту запросов в секунду. Службе с политикой частоты может потребоваться выравнивание темпа или отдельный ограничитель частоты.
Выбирайте стабильный, несекретный идентификатор прокси для журналов и метрик. Если два URL с учётными данными ссылаются на один и тот же пул ёмкости, решите, должны ли они делить один бюджет. И наоборот, разные порты или учётные записи могут представлять отдельные лимиты, если оператор документирует их именно так.
Когда пропускная способность падает, проверьте, где ждёт работа: ваш семафор, коннектор, установка соединения с прокси или чтение ответов. Одновременное повышение всех лимитов усложняет это различие и может переместить очередь в прокси, который вы не контролируете.