Flask教程(二十)flask-apscheduler

与 flask 集成时, 多 work 管理问题

2020-10-08

文章目录

软硬件环境

视频看这里

此处是youtube的播放链接,需要科学上网。喜欢我的视频,请记得订阅我的频道,打开旁边的小铃铛,点赞并分享,感谢您的支持。

前言

前文 Python实用模块之apscheduler 已经介绍过的基本使用了。flask - apschedulerapscheduler移植到了flask应用中,使得在flask中可以非常方便的使用定时任务了,除此之外,它还有如下几个特性

  • 根据Flask配置加载调度器配置
  • 根据Flask配置加载任务调度器
  • 允许指定服务器运行任务
  • 提供RESTful API管理任务,也就是远程管理任务
  • RESTful API提供认证

使用示例

在使用之前,我们需要安装这个模块,使用pip

  1. pip install flask-apscheduler

flask-apscheduler的相关配置,我们会将它和其它扩展一起,放在应用的配置里,下面先来看个间隔定时任务

  1. from flask import Flask
  2. from flask_apscheduler import APScheduler
  3. class Config(object):
  4. JOBS = [
  5. {
  6. 'id': 'job1',
  7. 'func': 'run:add',
  8. 'args': (1, 2),
  9. 'trigger': 'interval',
  10. 'seconds': 3
  11. }
  12. ]
  13. SCHEDULER_API_ENABLED = True
  14. def add(a, b):
  15. print(a+b)
  16. if __name__ == '__main__':
  17. app = Flask(__name__)
  18. app.config.from_object(Config())
  19. scheduler = APScheduler()
  20. scheduler.init_app(app)
  21. scheduler.start()
  22. app.run()

Config类里,有一个列表JOBS,每个元素是一项任务,上面的示例代码中只有一个任务,是一个interval任务,每3秒执行一次,具体执行的任务方法是add,接收2个参数。func后面的值格式是 模块名:方法名

flask app实例化后,运行之前,我们进行flask-apscheduler的初始化,这一步必不可少

  1. scheduler = APScheduler()
  2. scheduler.init_app(app)
  3. scheduler.start()

执行上面的工程,我们可以得到

  1. (FlaskTutorial) D:\xugaoxiang\FlaskTutorial\Flask-20-apscheduler>python run.py
  2. * Serving Flask app "run" (lazy loading)
  3. * Environment: production
  4. WARNING: This is a development server. Do not use it in a production deployment.
  5. Use a production WSGI server instead.
  6. * Debug mode: off
  7. * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
  8. 3
  9. 3
  10. 3

上边我们设置了SCHEDULER_API_ENABLED = True,可以通过访问 http://127.0.0.1:5000/scheduler ,其中scheduler是默认的RESTful API前缀

Flask教程(二十)flask-apscheduler - 迷途小书童的Note迷途小书童的Note - 图1

通过查看源码文件scheduler.py,我们可以看到flask-apscheduler为我们提供了哪些RESTful API

  1. def _load_api(self):
  2. """
  3. Add the routes for the scheduler API.
  4. """
  5. self._add_url_route('get_scheduler_info', '', api.get_scheduler_info, 'GET')
  6. self._add_url_route('add_job', '/jobs', api.add_job, 'POST')
  7. self._add_url_route('get_job', '/jobs/<job_id>', api.get_job, 'GET')
  8. self._add_url_route('get_jobs', '/jobs', api.get_jobs, 'GET')
  9. self._add_url_route('delete_job', '/jobs/<job_id>', api.delete_job, 'DELETE')
  10. self._add_url_route('update_job', '/jobs/<job_id>', api.update_job, 'PATCH')
  11. self._add_url_route('pause_job', '/jobs/<job_id>/pause', api.pause_job, 'POST')
  12. self._add_url_route('resume_job', '/jobs/<job_id>/resume', api.resume_job, 'POST')
  13. self._add_url_route('run_job', '/jobs/<job_id>/run', api.run_job, 'POST')

它们的使用方法是这样的,比如我要查看当前应用中的所有任务,可以访问使用GET方法访问 http://127.0.0.1:5000/scheduler/jobs

Flask教程(二十)flask-apscheduler - 迷途小书童的Note迷途小书童的Note - 图2

如果不习惯使用配置的话,还可以使用装饰器的方式,来看下面的示例

  1. from flask import Flask
  2. from flask_apscheduler import APScheduler
  3. class Config(object):
  4. SCHEDULER_API_ENABLED = True
  5. scheduler = APScheduler()
  6. @scheduler.task('interval', id='do_job_1', seconds=30)
  7. def job1():
  8. print('Job 1 executed')
  9. # cron examples
  10. @scheduler.task('cron', id='do_job_2', minute='*')
  11. def job2():
  12. print('Job 2 executed')
  13. @scheduler.task('cron', id='do_job_3', week='*', day_of_week='sun')
  14. def job3():
  15. print('Job 3 executed')
  16. if __name__ == '__main__':
  17. app = Flask(__name__)
  18. app.config.from_object(Config())
  19. scheduler.init_app(app)
  20. scheduler.start()
  21. app.run()

最后再来看个复杂点的配置

  1. class Config(object):
  2. JOBS = [
  3. {
  4. 'id': 'job1',
  5. 'func': 'run:job1',
  6. 'args': (1, 2),
  7. 'trigger': 'interval',
  8. 'seconds': 10
  9. }
  10. ]
  11. SCHEDULER_JOBSTORES = {
  12. 'default': SQLAlchemyJobStore(url='sqlite://')
  13. }
  14. SCHEDULER_EXECUTORS = {
  15. 'default': {'type': 'threadpool', 'max_workers': 20}
  16. }
  17. SCHEDULER_JOB_DEFAULTS = {
  18. 'coalesce': False,
  19. 'max_instances': 3
  20. }
  21. SCHEDULER_API_ENABLED = True

其中SCHEDULER_JOBSTORES指的就是作业存储器,我们把它存储到sqlite中。SCHEDULER_EXECUTORS指的是执行器的配置,使用的类型是threadpool线程池,且设置最大线程数为20。SCHEDULER_JOB_DEFAULTS是任务的一些配置,其中

  • coalesce指的是当由于某种原因导致某个任务积攒了好多次没有实际运行(比如说系统挂了2分钟后恢复,比如supervisor的进程监控工具,有一个任务是每分钟跑一次的,按道理说这2分钟内本来是计划要运行2次的,但实际没有执行),如果coalesceTrue,下次这个任务被执行时,只会执行1次,也就是最后这次,如果为False,那么会执行2次
  • max_instance就是说同一个任务同一时间最多有几个实例在跑

SCHEDULER_API_ENABLED指定是否开启API

除了上面的常用配置之外,还有一些

  1. SCHEDULER_TIMEZONE # 配置时区
  2. SCHEDULER_API_PREFIX # 配置API路由前缀
  3. SCHEDULER_ENDPOINT_PREFIX # 配置API路由后缀
  4. SCHEDULER_ALLOWED_HOSTS # 配置访问白名单
  5. SCHEDULER_AUTH # 配置认证中心

在服务器上部署flask应用的时候,经常需要设置时区,否则会报错

  1. class Config(object):
  2. SCHEDULER_TIMEZONE = 'Asia/Shanghai'

配置RESTful API路由的前缀和后缀

  1. class Config(object):
  2. SCHEDULER_API_PREFIX ='/xugaoxiang'

那么访问所有任务的路由就会由原来的 http://127.0.0.1:5000/scheduler/jobs 变成 http://127.0.0.1:5000/xugaoxiang/jobs

如果需要设定只允许某些主机访问的话,可以设置白名单,如果是允许全部的话,也可以写上*

  1. class Config(object):
  2. SCHEDULER_ALLOWED_HOSTS = ['xugaoxiang.com']

如果要添加认证的话,可以这样实现

  1. from flask import Flask
  2. from flask_apscheduler import APScheduler
  3. from flask_apscheduler.auth import HTTPBasicAuth
  4. class Config(object):
  5. JOBS = [
  6. {
  7. 'id': 'job1',
  8. 'func': 'run2:add',
  9. 'args': (1, 2),
  10. 'trigger': 'interval',
  11. 'seconds': 3
  12. }
  13. ]
  14. SCHEDULER_API_ENABLED = True
  15. SCHEDULER_AUTH = HTTPBasicAuth()
  16. def add(a, b):
  17. print(a+b)
  18. if __name__ == '__main__':
  19. app = Flask(__name__)
  20. app.config.from_object(Config())
  21. scheduler = APScheduler()
  22. # it is also possible to set the authentication directly
  23. # scheduler.auth = HTTPBasicAuth()
  24. scheduler.init_app(app)
  25. scheduler.start()
  26. @scheduler.authenticate
  27. def authenticate(auth):
  28. return auth['username'] == 'guest' and auth['password'] == 'guest'
  29. app.run()

在访问scheduler之前,先做一次认证,如果满足条件,如上面通过http请求传递过来的参数username=guestpassword=guest,就可以继续访问,否则拒绝访问。

源码下载

https://github.com/xugaoxiang/FlaskTutorial

Flask教程专题

更多Flask教程,请移步

https://xugaoxiang.com/category/python/flask/

参考资料