async def gen():
    for chunk in chunks:
        if await request.is_disconnected():
            break
        yield chunk

用户点导出等 30 秒没反应直接关页面,服务端日志显示仍在读 80 万行,十分钟后任务队列积压 200 个,新请求全部排队。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:生成逻辑只负责往响应里写,没有检查客户端是否还在,连接断开后写操作失败但循环继续。任务也没有超时和取消入口,只能等它自己跑完。

围绕「导出客户端断开」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。同一份配置存在多处的,先确认改的是被加载的那一份。

新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

处理上按这个顺序:每写一批检查 request.is_disconnected 为真就退出循环;给导出任务加总超时 超过 10 分钟直接终止并记录;把重活挪到后台任务 前端用任务号轮询结果。

确认没问题再收工,关掉页面后服务端日志在 2 秒内出现 client disconnected 并停止读取,队列长度回落到个位数。

作者 9823189