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

如何处理超出Heroku超时限制的异步HTTP视图请求?

解决Heroku上Flask异步端点超时问题

核心思路

问题根源是你的端点在等待异步定时器任务完成才返回响应,超出了Heroku的30秒请求时限。要保留多定时器逻辑,必须把请求响应流程和异步任务执行解耦——请求进来后立即返回成功状态,任务在后台独立运行。

具体实现方案

1. 改造Flask异步视图,启动任务后立即返回

Flask 2.0+支持异步视图,你可以在视图里启动asyncio后台任务,不等待其完成直接返回响应。示例代码:

import asyncio
from flask import Flask, jsonify

app = Flask(__name__)

async def fetch_sports_data_periodically(interval):
    # 你的多定时器抓取逻辑
    while True:
        # 执行数据抓取操作
        print("正在抓取体育数据...")
        await asyncio.sleep(interval)

@app.route('/api/fixtures_data', methods=['GET'])
async def fixtures_data():
    # 启动后台定时器任务,不等待完成
    asyncio.create_task(fetch_sports_data_periodically(60))  # 示例间隔60秒
    # 立即返回响应
    return jsonify({"status": "success", "message": "定时数据抓取任务已启动"}), 202

2. 用独立Worker进程承载长期定时任务

如果你的任务需要持续运行(比如全天定时抓取),仅靠Web进程的后台任务不稳定——Heroku的Web进程可能因闲置或重启被回收,导致任务中断。此时需要:

  • 将定时任务移到独立的Worker进程中运行,与Web进程分离。
  • 通过Heroku的Procfile配置多进程管理。

示例Procfile配置:

web: uvicorn your_app:app --host=0.0.0.0 --port=${PORT:-5000}
worker: python worker.py

worker.py示例(保留多定时器逻辑):

import asyncio
import time

async def fetch_sports_data_periodically(interval):
    while True:
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 正在抓取体育数据...")
        # 执行数据抓取操作
        await asyncio.sleep(interval)

async def main():
    # 启动多个不同间隔的定时器任务
    tasks = [
        fetch_sports_data_periodically(60),
        fetch_sports_data_periodically(300)
    ]
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

3. 额外注意事项

  • 绝对不要在Web视图中await长时间运行的异步任务,否则会导致请求挂起直到任务完成,再次触发超时。
  • 若需要反馈任务执行状态,可以在数据库或缓存中记录任务进度,新增一个/api/task_status端点供查询。
  • Heroku免费Worker进程有休眠限制,如需24小时不间断运行,需升级到付费计划。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:07:46