Python 实现定时任务的八种方案( 五 )


目前APScheduler定义的Event:

  • EVENT_SCHEDULER_STARTED
  • EVENT_SCHEDULER_START
  • EVENT_SCHEDULER_SHUTDOWN
  • EVENT_SCHEDULER_PAUSED
  • EVENT_SCHEDULER_RESUMED
  • EVENT_EXECUTOR_ADDED
  • EVENT_EXECUTOR_REMOVED
  • EVENT_JOBSTORE_ADDED
  • EVENT_JOBSTORE_REMOVED
  • EVENT_ALL_JOBS_REMOVED
  • EVENT_JOB_ADDED
  • EVENT_JOB_REMOVED
  • EVENT_JOB_MODIFIED
  • EVENT_JOB_EXECUTED
  • EVENT_JOB_ERROR
  • EVENT_JOB_MISSED
  • EVENT_JOB_SUBMITTED
  • EVENT_JOB_MAX_INSTANCES
Listener表示用户自定义监听的一些Event,比如当Job触发了EVENT_JOB_MISSED事件时可以根据需求做一些其他处理 。
调度器Scheduler是APScheduler的核心,所有相关组件通过其定义 。scheduler启动之后,将开始按照配置的任务进行调度 。除了依据所有定义Job的trigger生成的将要调度时间唤醒调度之外 。当发生Job信息变更时也会触发调度 。
APScheduler支持的调度器方式如下,比较常用的为BlockingScheduler和BackgroundScheduler
  • BlockingScheduler:适用于调度程序是进程中唯一运行的进程,调用start函数会阻塞当前线程,不能立即返回 。
  • BackgroundScheduler:适用于调度程序在应用程序的后台运行,调用start后主线程不会阻塞 。
  • AsyncIOScheduler:适用于使用了asyncio模块的应用程序 。
  • GeventScheduler:适用于使用gevent模块的应用程序 。
  • TwistedScheduler:适用于构建Twisted的应用程序 。
  • QtScheduler:适用于构建Qt的应用程序 。
Scheduler的工作流程Scheduler添加job流程:
Python 实现定时任务的八种方案

文章插图
 
Scheduler调度流程:
Python 实现定时任务的八种方案

文章插图
 
使用分布式消息系统Celery实现定时任务Celery是一个简单,灵活,可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需的工具, 也可用于任务调度 。Celery 的配置比较麻烦,如果你只是需要一个轻量级的调度工具,Celery 不会是一个好选择 。
Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行 。我们通常使用它来实现异步任务(async task)和定时任务(crontab) 。异步任务比如是发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作 ,定时任务是需要在特定时间执行的任务 。
需要注意,celery本身并不具备任务的存储功能,在调度任务的时候肯定是要把任务存起来的,因此在使用celery的时候还需要搭配一些具备存储、访问功能的工具,比如:消息队列、Redis缓存、数据库等 。官方推荐的是消息队列RabbitMQ,有些时候使用Redis也是不错的选择 。
它的架构组成如下图:
Python 实现定时任务的八种方案

文章插图
 
Celery架构,它采用典型的生产者-消费者模式,主要由以下部分组成:
  • Celery Beat,任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列 。
  • Producer:需要在队列中进行的任务,一般由用户、触发器或其他操作将任务入队,然后交由workers进行处理 。调用了Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者 。
  • Broker,即消息中间件,在这指任务队列本身,Celery扮演生产者和消费者的角色,brokers就是生产者和消费者存放/获取产品的地方(队列) 。
  • Celery Worker,执行任务的消费者,从队列中取出任务并执行 。通常会在多台服务器运行多个消费者来提高执行效率 。
  • Result Backend:任务处理完后保存状态信息和结果,以供查询 。Celery默认已支持Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy等方式 。
实际应用中,用户从Web前端发起一个请求,我们只需要将请求所要处理的任务丢入任务队列broker中,由空闲的worker去处理任务即可,处理的结果会暂存在后台数据库backend中 。我们可以在一台机器或多台机器上同时起多个worker进程来实现分布式地并行处理任务 。
Celery定时任务实例:
  • Python Celery & RabbitMQ Tutorial
  • Celery 配置实践笔记
使用数据流工具Apache Airflow实现定时任务Apache Airflow 是Airbnb开源的一款数据流程工具,目前是Apache孵化项目 。以非常灵活的方式来支持数据的ETL过程,同时还支持非常多的插件来完成诸如HDFS监控、邮件通知等功能 。Airflow支持单机和分布式两种模式,支持Master-Slave模式,支持Mesos等资源调度,有非常好的扩展性 。被大量公司采用 。


推荐阅读