You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asyncio http server循环配置:非阻塞添加aiohttp到循环列表后服务无法启动

问题根因

核心问题是web.run_app的调用不符合多异步任务共用事件循环的场景要求:

  • web.run_app是同步阻塞函数,内部会独占事件循环运行直到服务终止,放在协程中直接调用会直接卡死当前异步调度逻辑,导致服务无法正常启动,其他异步任务也无法运行。
  • 你提前将self.webLoop()协程实例放入数组中,第一次await asyncio.gather执行完成后该协程就会进入已结束状态,下次循环再次传入会直接抛出协程不可重用的报错。
  • 新版本aiohttp已经废弃了在web.Application构造时传入loop参数的写法,手动指定loop没有必要。
  • 路由处理函数webPing的第一个参数是aiohttp传入的请求对象,参数名写为handler属于不规范写法,不会影响运行但建议修正。
修复方案

使用aiohttp提供的AppRunner+TCPSite手动挂载服务,实现非阻塞和其他异步任务共同运行:

import asyncio
import logging
from aiohttp import web

log = logging.getLogger(__name__)

# 类内部方法示例
async def webPing(self, request):
    text = "OK"
    return web.Response(text=text)

async def webLoop(self):
    self.app = web.Application()
    self.app.add_routes([web.get('/ping', self.webPing)])
    # 手动初始化服务
    runner = web.AppRunner(self.app)
    await runner.setup()
    site = web.TCPSite(runner, port=8080)
    await site.start()
    # 保持服务运行直到触发 shutdown 标记
    while not self.shutdown:
        await asyncio.sleep(1)
    # 退出前清理服务资源
    await runner.cleanup()

async def runMe(self):
    while not self.shutdown:
        try:
            # 可在gather中同时添加其他需要并行的异步任务
            await asyncio.gather(
                self.webLoop(),
                # 其他异步任务...
            )
        except Exception as e:
            log.error(f'Unhandled exception in gather loop {e}')
            # 异常后延迟1秒再重启,避免无限快速报错占用资源
            await asyncio.sleep(1)

内容的提问来源于stack exchange,提问作者Miro Krsjak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:27:03