将多个HTTP GET请求发送到同一主机会导致aiohttp客户端卡住

时间:2019-06-09 10:55:33

标签: python aiohttp

我正在尝试向同一主机发送多个请求(例如,我试图通过使用来自同一主机的六个TCP连接来下载20-50个文件)

这是循环完成的,这意味着在我完成一组文件的下载之后,继续执行代码并下载一组新的文件,依此类推。

当我要下载20个以上的文件时,出现问题。客户端被卡住,并且不会释放进程。此外,我与Wireshark进行了检查,一切似乎都正常运行,所有请求均已发送(GET),所有响应均已收到(200 / OK)。似乎逻辑的实现方式或库本身中的错误都存在问题。

超时始终带有以下消息:

异步-信息-轮询14805.463毫秒耗时14808.587毫秒:超时

我正在使用aiohttp版本3.5.4和Python 3.7.2

对于Web服务器,我使用服务员+ Flask来提供文件

当我切换到HTTP 1.0时,它可以正常工作。持久连接似乎出现问题。我希望保持连接打开状态

导入aiohttp 导入日志 始终导入

async def download_site(会话,URL):

 response = await session.request(method="GET", url=url[0], params=url[1], ssl=False, expect100=False)
 async with response:
     stat = response.status 
     response.release()
     return stat

异步定义检索文件(_file,运行):

headers = {"Connection": "keep-alive"}
async with aiohttp.ClientSession(headers=headers, connector=aiohttp.TCPConnector(limit=6), raise_for_status=True) as session:
    start_time = time.time()
    # we first download main file (actually this is not always one)
    num_main_file = 1   


    for main_obj in range(1, num_main_obj+1):

            # auxilary files
            # list object is a list of auxilary file names which we use to construct a list of requests
            inline_objs = [["127.0.0.1:8080", {'user': '1', 'file': str(_file), 'run':str(run), 'obj':i}] for i in list_obj]


            # download main file
            main_list = [["127.0.0.1:8080", {'user': '1', 'file': str(_file), 'run':str(run), 'obj':"main_%d"%main_obj}]]
            tasks = []
            for url in main_list:
                task = asyncio.create_task(download_site(session, url))
                tasks.append(task)
            res = await asyncio.gather(*tasks, return_exceptions=True)
            logging.debug("main obj: " + str(res))

            # download auxilary files - this is where problem happens
            tasks = []
            for url in inline_objs:
                task = asyncio.create_task(download_site(session, url))
                tasks.append(task)
            res = await asyncio.gather(*tasks, return_exceptions=True)
            logging.debug("inline objs: " + str(res))

    duration = int(1000*(time.time() - start_time))
    logging.info('Load File_%d: %d'%(_file, duration))
    await asyncio.sleep(0.001)

异步def包装(_file,运行):     尝试:         #添加超时,因为默认情况下它将停留约300秒         等待asyncio.wait_for(retrieve_file( file,run),timeout = 15.0)     除了asyncio.TimeoutError:         logging.info('文件%d:超时'%(_ file))

def main(** kwargs):

# we try this five times
for run in range(1, 6):

    for _file in range(1, num_files+1):

        # create session
        asyncio.run(wrap(_file, run), debug=True)
        # sleep for 2 seconds
        time.sleep(2.0)

如果名称 ==“ 主要”:

# set logging level
logging.basicConfig(filename='test.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s', level=logging.DEBUG)
main()

这是正常运行时始终记录的输出:

root-DEBUG-main obj:[200]-下载的主文件

asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 13读取=轮询写入=>,) 异步-调试-已连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 14读取=轮询写入=>,) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 15读取=轮询写入=>,) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 16读取=轮询写入=>,) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 17读取=轮询写入=>,) 异步-调试-轮询14959.065毫秒耗时0.817毫秒:1个事件 asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-轮询14956.670毫秒耗时0.009毫秒:1个事件 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 15读取=轮询写入=>,) 异步-调试-轮询14948.205毫秒耗时0.046毫秒:1个事件 asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-轮询14946.960毫秒耗时0.010毫秒:2个事件 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 13读取=轮询写入=>,) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-已连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 14读取=轮询写入=>,) 异步-调试-轮询14935.982 ms耗时0.053 ms:1个事件 异步-调试-轮询14935.441毫秒耗时0.227毫秒:1个事件 根-调试-内联objs:[200、200、200、200、200、200、200、200、200、200、200、200、200、200、200、200、200、200、200、200, 200、200、200、200、200、200、200、200]-使用6个TCP连接下载了所有aux文件 根-信息-加载File_7:65

这是超时出现的时间:

root-DEBUG-main obj:[200]-下载的主文件

asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-已连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 14读取=轮询写入=>,) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 15读取=轮询写入=>,) 异步-调试-<_SelectorSocketTransport fd = 13读取=空闲写入=>暂停读取 asyncio-调试-连接到('127.0.0.1',8080) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-已连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 14读取=轮询写入=>,) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 16读取=轮询写入=>,) 异步-调试-轮询14825.699毫秒耗时0.205毫秒:1​​个事件 asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-轮询14824.048毫秒耗时0.017毫秒:5个事件 异步-调试-已连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 12读=轮询写=>,) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-轮询14817.963毫秒耗时0.008毫秒:2个事件 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 15读取=轮询写入=>,) asyncio-调试-连接到('127.0.0.1',8080) 异步-调试-连接到127.0.0.1:8080:(<_SelectorSocketTransport fd = 17读取=轮询写入=>,) 异步-调试-轮询14807.080毫秒耗时0.948毫秒:1个事件 异步-信息-轮询14805.463毫秒耗时14808.587毫秒:超时-这始终会出现 根-信息-File_8:超时

0 个答案:

没有答案