Aiohttp.ClientSession проблема при работе с большим количеством запросов через proxy
Я создаю большое количество сессий 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к