我正在尝试从数百万个不同的站点获取状态代码,我使用的是asyncio和aiohttp,我使用不同数量的连接运行以下代码(但请求的相同超时)但是获得了非常不同的结果,特别是更高的数量以下例外 .
'concurrent.futures._base.TimeoutError'
代码
import pandas as pd
import asyncio
import aiohttp
out = []
CONNECTIONS = 1000
TIMEOUT = 10
async def fetch(url, session, loop):
try:
async with session.get(url,timeout=TIMEOUT) as response:
res = response.status
out.append(res)
return res
except Exception as e:
_exception = 'Error: '+str(type(e))
out.append(_exception)
return _exception
async def bound_fetch(sem, url, session, loop):
async with sem:
await fetch(url, session, loop)
async def run(urls, loop):
tasks = []
sem = asyncio.Semaphore(value=CONNECTIONS,loop=loop)
_connector = aiohttp.TCPConnector(limit=CONNECTIONS, loop=loop)
async with aiohttp.ClientSession(connector=_connector,loop=loop) as session:
for url in urls:
task = asyncio.ensure_future(bound_fetch(sem, url, session, loop))
tasks.append(task)
responses = await asyncio.gather(*tasks,return_exceptions=True)
return responses
## BEGIN ##
tlds = open('data/sample_1k.txt').read().splitlines()
urls = ['http://{}'.format(x) for x in tlds[1:]]
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(urls,loop))
ans = loop.run_until_complete(future)
print(str(pd.Series(out).value_counts()))
结果
CONNECTIONS = 1000
连接= 100
这是一个错误吗?这些站点使用状态代码进行响应并按顺序运行或使用较低的连接没有超时错误,为什么会发生这种情况?当您更改连接数时,其他异常似乎很稳定 . ClientOSErrors来自实际超时或响应的站点,老实说,并不真正知道concurrent.futures._base.TimeoutError错误的来源 .
2 回答
想象一下,你在浏览器中同时打开了1000个网址 . 我打赌你会注意到他们中的许多人在10秒后没有装满 . 这不是一个错误,它是您的机器资源的限制 .
您正在做的更多并行请求 - >每个请求的网络容量更少,每个CPU占用的CPU时间更少,每个请求的RAM更少 - >每个请求在超时之前没有准备好的可能性更高 .
如果您看到有1000个连接有很多超时,请减少连接(并且可能会增加超时) . 基于
aiohttp
documentation使用不同的ClientSession
实例也可能有所帮助:我有同样的问题,看看
ClientOSError
的详细信息,您可能会看到Too many open files
,如果是这样,您需要增加操作系统的文件描述符数量 .无论哪种方式,如果您打印整个异常,而不仅仅是他们的类型,您将获得更多信息 .