我正在尝试从数百万个不同的站点获取状态代码,我正在使用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
CONNECTIONS = 100
这是一个错误吗?这些站点使用状态代码进行响应并按顺序运行或使用较低的连接没有超时错误,为什么会发生这种情况?当您更改连接数时,其他异常似乎很稳定。 ClientOSErrors来自实际超时或响应的站点,老实说,并不真正知道concurrent.futures._base.TimeoutError错误的来源。
答案 0 :(得分:3)
想象一下,您同时在浏览器中打开了1000个网址。我打赌你会注意到他们中的许多人在10秒后没有装好。这不是一个错误,它限制了您的机器资源。
您正在进行的更多并行请求 - >每个网络容量减少,每个网络的CPU时间减少,每个网络的RAM减少 - >每个请求在超时之前都没有准备好的可能性更高。
如果您看到有1000个连接有很多超时,请减少连接(并且可能会增加超时)。基于aiohttp
documentation使用不同的ClientSession
个实例也可能会有所帮助:
除非你连接到一个大的,未知数量的不同 在您的应用程序的生命周期内,建议您使用 应用程序生命周期内的单个会话
答案 1 :(得分:2)
我有同样的问题,请查看ClientOSError
的详细信息,您可能会看到Too many open files
,如果需要,您需要增加操作系统的号码文件描述符。
无论哪种方式,如果您打印整个例外而不仅仅是他们的类型,您将获得更多信息。