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

如何部署Python Worker到Heroku且避免推送后自动运行?

解决方案说明

问题根源

Heroku 在部署代码时会自动启动 Procfile 中定义的所有 dyno,你的 worker: python main.py 配置会让 worker dyno 启动后立即执行 main.py,这就是每次推送代码时脚本自动运行的原因。

可行的解决方法

方法1:用 Heroku Scheduler 直接触发任务,关闭持久化 worker dyno

  • 操作步骤:
    1. 部署代码后,执行命令将 worker dyno 缩容到0:
      heroku ps:scale worker=0
      
      也可以在 Heroku 控制台的应用设置中配置默认 worker 数量为0,避免每次部署后手动操作。
    2. 在 Heroku Scheduler 中设置每日任务,直接运行命令:
      python main.py
      
  • 优势:无需修改脚本,仅通过配置即可解决问题,且仅在任务触发时占用 dyno 资源,成本更低。

方法2:修改脚本,仅在调度触发时执行核心逻辑

  • 修改脚本:在 main.py 中添加环境变量检查,只有特定变量存在时才运行核心代码:
    import os
    
    def main():
        # 原有的脚本逻辑
        pass
    
    if __name__ == "__main__":
        # 仅当环境变量 RUN_FROM_SCHEDULER 为 true 时执行
        if os.getenv("RUN_FROM_SCHEDULER") == "true":
            main()
        else:
            print("非调度触发,退出脚本")
    
  • 配置调度器:在 Heroku Scheduler 中设置任务命令为:
    RUN_FROM_SCHEDULER=true python main.py
    
  • 优势:保留 worker dyno 配置,但部署时脚本不会执行核心逻辑,仅在调度触发时运行。

方法3:使用 APScheduler 内置调度(可行,需修改脚本)

  • 修改脚本:将调度逻辑集成到脚本中,让 worker dyno 持续运行并等待调度触发:
    from apscheduler.schedulers.blocking import BlockingScheduler
    import datetime
    
    def job():
        # 原有的脚本逻辑
        print(f"执行任务:{datetime.datetime.now()}")
    
    if __name__ == "__main__":
        scheduler = BlockingScheduler()
        # 配置每天特定时间运行(示例为 UTC 时间3点)
        scheduler.add_job(job, 'cron', hour=3, minute=0)
        print("调度器已启动,等待下一次任务执行...")
        scheduler.start()
    
  • 注意事项:此方法需要 worker dyno 24小时持续运行,会占用更多 dyno 时长,成本高于 Heroku Scheduler,适合需要复杂调度规则(如多时段、间隔执行)的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:25:06