【问题标题】:Concurrency with aiohttp server与 aiohttp 服务器的并发
【发布时间】:2018-04-20 04:50:24
【问题描述】:

这是我的代码:

import asyncio
import logging
import time

from aiohttp import web

logging.getLogger('aiohttp').setLevel(logging.DEBUG)
logging.getLogger('aiohttp').addHandler(logging.StreamHandler(sys.stderr))

def handle_sync(request):
    web.web_logger.debug('Sync begin')
    time.sleep(10)
    web.web_logger.debug('Sync end')
    return web.Response(text='Synchronous hello')


async def handle_async(request):
    web.web_logger.debug('Async begin')
    await asyncio.sleep(10)
    web.web_logger.debug('Async end')
    return web.Response(text='Asynchronous hello')


async def init(loop):
    app = web.Application(loop=loop)
    app.router.add_get('/sync/', handle_sync)
    app.router.add_get('/async/', handle_async)

    srv = await loop.create_server(app.make_handler(), '0.0.0.0', 8080)
    return srv

loop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()

我希望有两种行为:

  • 当点击两次/sync/ url 时,假设间隔为 2 秒,总时间为 20 秒,因为我们在一个线程中有一个服务器,并且有一个阻塞调用
  • 以相同方式点击两次/async/ url 的总时间为 12 秒(这些调用是异步的,对吗?)

但这两种情况似乎都持续了 20 秒,有人可以解释一下原因吗?

【问题讨论】:

    标签: async-await python-asyncio aiohttp


    【解决方案1】:

    为了能够在此处观察使用异步的好处,您需要(几乎)同时发送两个单独的请求。

    await 调用仅仅意味着函数将控制权交给事件循环,以便如果发生任何其他事件,它们可以在不阻塞的情况下进行处理。如果您确实同时向异步端点发送了两个请求,您会看到每个请求都在 10 秒左右完成。这是因为两个请求是同时处理的:第一个请求不会阻止服务器处理另一个请求。

    但是,如果您以类似的方式向同步端点发送两个请求,则第二个请求将需要 20 秒。这是因为同步端点在第一个请求上阻塞并且在第一个请求完成之前无法开始为第二个请求提供服务。

    【讨论】:

    • 好吧,实际上你描述的是我所期望的,但不是发生了什么(仔细阅读描述):如果我点击异步部分,然后在 2 秒后再次点击,第二个到达不是 12开始后的几秒,但 20 !看起来那里没有异步。
    • 嗯..这当然很奇怪,因为我几乎逐字复制了您的代码(顶部缺少import sys,但这是我所做的唯一更改)。在大约 2 秒的时间内运行 time curl localhost:8080/async/ & 显示两个请求都在 10 秒内完成。请问您对端点的请求是如何提出的?
    • 我是通过浏览器 (Firefox) 进行的,而不是以编程方式进行的……这可能是原因吗?我忘了感谢你的帮助,所以谢谢!
    • 不客气 :)。我不会想象它本身就是浏览器。但是,例如,如果请求是从同一个选项卡发送的,那么确实会导致您遇到的行为。为了获得更准确的时间,我会使用curl(或命令行中可用的任何其他内容。
    • 你是对的,使用 curl 可以!通过 Firefox 进行的会话处理或其他任何事情(我注意使用 2 个单独的选项卡)一定令人不安……非常感谢!
    猜你喜欢
    • 2017-03-29
    • 2022-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    相关资源
    最近更新 更多