Heroku上APScheduler cron任务较预定时间早5小时执行如何修复
问题原因
5小时的时间偏差是时区配置缺失导致的:
- Heroku 运行环境默认使用
UTC时区,APScheduler 初始化时如果不显式指定时区,会直接读取宿主系统的时区作为cron任务的触发时间基准 - 第一周运行正常是因为部署初期dyno未触发重启,临时时区配置未被重置;周末时段Heroku免费dyno会自动休眠重启,回退到默认UTC时区,最终导致触发时间偏移。UTC时间比美东时间(UTC-5)快5小时,刚好匹配你遇到的「预定下午3点触发、实际上午10点发信」的现象。
修复方案
1. 初始化调度器时显式指定目标时区
修改调度器初始化代码,传入你实际需要使用的时区标识(美东时间填America/New_York,北京时间填Asia/Shanghai,按自身业务需求替换即可),修正后完整代码如下:
from apscheduler.schedulers.blocking import BlockingScheduler from run import admin_operations, check_list, getData from urls import stock_urls # 显式指定时区,从根源避免系统默认时区变动影响任务触发 sched = BlockingScheduler(timezone="America/New_York") @sched.scheduled_job('cron', day_of_week='mon-fri', hour=15) def scheduled_job(): admin_operations() users = check_list() urls = stock_urls.copy() getData(urls, users) sched.start()
如果项目内有多个定时任务需要使用不同时区,也可以直接给@sched.scheduled_job装饰器单独传入timezone参数,该配置优先级高于调度器的全局时区设置。
2. 配置Heroku时区环境变量做双重校准
在本地项目目录下执行Heroku CLI命令,给应用配置和代码一致的TZ环境变量,避免后续dyno重启、平台底层配置调整带来的时区变动问题:
heroku config:add TZ="America/New_York"
3. 配置验证
部署更新后,可以先临时把cron触发时间调整到当前时间后2-3分钟,验证发信时间是否符合预期,确认无误后再改回15点的正式配置即可。
内容的提问来源于stack exchange,提问作者JayTicku
相关产品推荐
相关产品推荐

