Aiohttp.ClientSession проблема при работе с большим количеством запросов через proxy

Рейтинг: 0Ответов: 0Опубликовано: 10.06.2023

Я создаю большое количество сессий aiohttp.ClientSession и отправляю запросы через http-proxy.

Пример кода прикладываю

Все работает корректно, до того момента , как я пытаюсь одновременно отправить более чем 4-5к запросов, но при попытке создать более чем 5к сессий и отправлять постоянно запросы через прокси, я получаю следующее поведение: после примерно 3-4к успешно отправленных запросов, я перестаю получать вывод принтов ( которые показывают количество выполненных запросов), и далее ничего не происходит, я не получаю ответов с запросов и ровно также не получаю каких-либо ошибок, по типу TimeoutError. Цикл обработки событий не завершается, и все открытые соединения не закрываются.

Netstat показывает, что висит куча соединений со статусом close_wait

введите сюда описание изображения

Если не использовать прокси, все происходит нормально, спустя некоторое время, в районе 40-50 секунд, я получаю результат обработки всех запросов. Я пробовал устанавливать timeout, в конфигурации запроса session.get(timeout=20), и получается следующее, если я устанавливаю тайм-аут менее 20 секунд, я начинаю получать TimeoutError's как положено, и программа завершает цикл, но если установить значение таймаута более 20 секунд, например - 50, то я получаю ровно такой-же результат как я описал вначале.

Меня интересует , с чем может быть связано такое поведение aiohttp, и возможные решения. Я хотел бы иметь возможность установить значение timeout, большее чем 20 секунд, и при этом, получать результат обработки всех запросов, а не зависший цикл обработки событий (или что-то другое, но выглядещее именно так)

import requests
import asyncio
import aiohttp
from datetime import datetime
import random
import time    

with open(r'C:\Users\Administrator\Desktop\proxy.txt', 'r', encoding="utf-8") as f:
    proxies = f.read().split('\n')

async def create_sessions():
    sessions = []
    for i in range(10000):
        session = aiohttp.ClientSession()
        sessions.append(session)
    return sessions
    
done = 0

async def send_req(session, n, proxy):
    url = f'https://www.google.com/search?q=test'
    try:
        async with session.get(url, timeout=20, proxy = proxy) as resp:
            print(resp.status)
            # await resp.text()
            # print(resp.status)
            global done
            done+=1
            print(f"Requests done: {done}")
        return resp.status
    except Exception as e:
        print(e.__class__.__name__)
    finally:
        await session.close()

async def main():
    sessions = await create_sessions()
    tasks = []
    for n, session in enumerate(sessions):
        dsn = random.choice(proxies)
        parts = dsn.split(':')
        proxy = f"http://{parts[2]}:{parts[3]}@{parts[0]}:{parts[1]}"
        # print(proxy)

        tasks.append(asyncio.create_task(send_req(session, n, proxy=proxy)))
    start = datetime.now()

    result = []
    for task in tasks:
        result.append(await task)
    print(len(list(filter(lambda x:x == 200, result))))
    print(datetime.now()-start)
    await asyncio.sleep(1)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.stop()
time.sleep(1)
loop.close()

UPD: Решил проверить как поведут себя requests в связке с threading.Thread's , получил туже самую проблему, после создания 10к потоков, каждый из которых должен был отправить по запросу, получил результат только с 3к

Ответы

Ответов пока нет.