tl; dr : как максимально увеличить количество http-запросов, которые я могу отправлять параллельно?
Я получаю данные из нескольких URL-адресов с помощью библиотеки aiohttp
.Я тестирую его производительность, и я заметил, что где-то в процессе есть узкое место, где одновременный запуск нескольких URL-адресов просто не помогает.
Я использую этот код:
import asyncio
import aiohttp
async def fetch(url, session):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0'}
try:
async with session.get(
url, headers=headers,
ssl = False,
timeout = aiohttp.ClientTimeout(
total=None,
sock_connect = 10,
sock_read = 10
)
) as response:
content = await response.read()
return (url, 'OK', content)
except Exception as e:
print(e)
return (url, 'ERROR', str(e))
async def run(url_list):
tasks = []
async with aiohttp.ClientSession() as session:
for url in url_list:
task = asyncio.ensure_future(fetch(url, session))
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
return responses
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
task = asyncio.ensure_future(run(url_list))
loop.run_until_complete(task)
result = task.result().result()
Выполнение этого с url_list
различной длины (тесты против https://httpbin.org/delay/2) Я вижу, что добавление большего количества URL для одновременного запуска помогает только до ~ 100 URL, а затем общее время начинает растипропорционально количеству URL-адресов (или, другими словами, время на один URL-адрес не уменьшается). Это говорит о том, что что-то не получается при попытке обработать их одновременно. Кроме того, с большим количеством URL-адресов в «одном пакете» я иногда получаю тайм-аут соединенияошибки.
- Почему это происходит? Что именно ограничивает скорость здесь?
- Как я могу проверить, каково максимальное число параллельных запросов, которое я могу отправить на данный компьютер? (Я имею в виду точное число - не приблизительно "методом проб и ошибок", как указано выше)
- Что я могу сделать для увеличения количество запросов, обработанных за один раз?
Я запускаю это в Windows.
РЕДАКТИРОВАТЬ в ответ на комментарий:
Это те же данные с ограничением, установленным на None
.Лишь небольшое улучшение в конце, и есть много ошибок тайм-аута соединения с одновременной отправкой 400 URL.В итоге я использовал limit = 200
для своих фактических данных.