添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

当Wsgi服务器重启时重启ApScheduler Python中的工作

3 人关注

我正在使用python Apscheduler来安排我的工作。我所有的工作都存储为cron job,并使用BackgroundScheduler。我有以下的代码。

def letschedule():
    jobstores = {
        'default': SQLAlchemyJobStore(url=app_jobs_store)
    executors = {
        'default': ThreadPoolExecutor(20),
        'processpool': ProcessPoolExecutor(5)
    job_defaults = {
        'coalesce': False,
        'max_instances': 1,
        'misfire_grace_time':1200
    scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
    #jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc
    return scheduler

我在应用程序中启动了工作调度器,如下所示。

sch = letschedule()
sch.start()
log.info('the scheduler started')

而我有以下新增的工作职能。

def addjobs():
    jobs = []
        sch.add_job(forecast_jobs, 'cron', day_of_week=os.environ.get("FORECAST_WEEKOFDAY"),  
            id="forecast",
             replace_existing=False,week='1-53',hour=os.environ.get("FORECAST_HOUR"), 
             minute=os.environ.get("FORECAST_MINUTE"), timezone='UTC')
        jobs.append({'job_id':'forecast', 'type':'weekly'})
        log.info('the forecast added to the scheduler')
    except BaseException as e:
        log.info(e)
        sch.add_job(insertcwhstock, 'cron', 
            id="cwhstock_data", day_of_week='0-6', replace_existing=False,hour=os.environ.get("CWHSTOCK_HOUR"),
            minute=os.environ.get("CWHSTOCK_MINUTE"),
            week='1-53',timezone='UTC')
        jobs.append({'job_id':'cwhstock_data', 'type':'daily'})
        log.info('the cwhstock job added to the scheduler')
    except BaseException as e:
        log.info(e)
    return json.dumps({'data':jobs})

我在flask应用程序中使用了这个功能,我调用了/activatejobs,作业被添加到调度器中,并且工作正常。然而,当我重启wsgi服务器时,工作并没有再次启动,我必须删除.sqlite文件并重新添加工作。我想要的是,一旦调度程序启动,作业就应该自动重新启动(如果数据库中已经有作业的话)。 我试着用一些方法来得到这样的结果,但是做不到。如果有任何帮助,我将不胜感激。 谢谢。

5 个评论
因此,在你重启你的 uwsgi 的同一.sh中,你可以添加一行像 python startscheduler.py 或类似的内容,这样它就会在同一时间运行。
可以这么做,但是我已经用sqlite来存储作业了,因为调度器是在我重启mod_wsgi时启动的,所以我想调度器应该从数据库中调用作业。我不知道我是否错了。
你的sqlite只是在内存中存储,所以如果你需要一个更持久的解决方案,你可能需要使用mysql或postgres。另外,rq或celery可以用更强大的方式处理作业。
我还遇到了一个问题,在服务器或应用程序重启后,作业没有被重启。明确定义我添加作业的jobstore,解决了我的问题。所以我开始用job_stores添加作业,例如scheduler.add_job(jobstore='mongo', trigger='cron', minute=8)
哦,真的,但是正如apscheduler团队给我的建议,如果我想让我的作业自动重启,我就不能使用flaks/wsgi,所以我为作业创建了一个单独的进程。
python
flask
cron
mod-wsgi
apscheduler
user2906838
user2906838
发布于 2018-01-01
1 个回答
Matheus Rodrigues Guimaraes
Matheus Rodrigues Guimaraes
发布于 2021-10-21
已采纳
0 人赞同

我在使用FastApi框架时也遇到了同样的问题。在我的app.py中加入这段代码后,我可以解决这个问题。

scheduler = BackgroundScheduler()
pg_job_store = SQLAlchemyJobStore(engine=my_engine)
scheduler.add_jobstore(jobstore=pg_job_store, alias='sqlalchemy')
scheduler.start()

添加这段代码后,在我重启应用服务器后,我可以看到apscheduler日志在搜索工作。

2021-10-20 14:37:53,433 - apscheduler.scheduler - INFO     => Scheduler started
2021-10-20 14:37:53,433 - apscheduler.scheduler - DEBUG    => Looking for jobs to run
Jobstore default:
    No scheduled jobs