APScheduler是一个Python定时任务框架,使用起来十分方便。提供了基于日期、固定时间间隔以及crontab类型的任务,并且可以持久化任务、并以daemon方式运行应用。目前最新版本为3.0.x。
在APScheduler中有四个组件:
触发器(trigger)包含调度逻辑,每一个作业有它自己的触发器,用于决定接下来哪一个作业会运行。除了他们自己初始配置意外,触发器完全是无状态的。
作业存储(job store)存储被调度的作业,默认的作业存储是简单地把作业保存在内存中,其他的作业存储是将作业保存在数据库中。一个作业的数据讲在保存在持久化作业存储时被序列化,并在加载时被反序列化。调度器不能分享同一个作业存储。
执行器(executor)处理作业的运行,他们通常通过在作业中提交制定的可调用对象到一个线程或者进城池来进行。当作业完成时,执行器将会通知调度器。
调度器(scheduler)是其他的组成部分。你通常在应用只有一个调度器,应用的开发者通常不会直接处理作业存储、调度器和触发器,相反,调度器提供了处理这些的合适的接口。配置作业存储和执行器可以在调度器中完成,例如添加、修改和移除作业。
你需要选择合适的调度器,这取决于你的应用环境和你使用APScheduler的目的。通常最常用的两个:
– BlockingScheduler: 当调度器是你应用中唯一要运行的东西时使用。
– BackgroundScheduler: 当你不运行任何其他框架时使用,并希望调度器在你应用的后台执行。
安装APScheduler非常简单:pip install apscheduler
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 11 17:38:44 2019
@author: kyle
"""
__author__ = 'Aaron'
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from datetime import datetime
import pandas as pd
import demjson
import my_logging
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.events import *
from apscheduler.events import EVENT_JOB_EXECUTED,EVENT_JOB_REMOVED,EVENT_JOB_MAX_INSTANCES, EVENT_JOB_ERROR, EVENT_JOB_MISSED,EVENT_JOB_ADDED,EVENT_JOB_MODIFIED
from pytz import utc
from apscheduler.jobstores.memory import MemoryJobStore
import time
import redis
def job_dict1():
list_dict = []
#------------------------能源管理-----------------------------------------------------------#
#执行时报统计,#定时每个小时的第几分钟执行
list_dict.append({
'jobid':'add_statistics_hours_epi',
'trigger': dict(minute=3),
'name':'add_statistics_hours_epi',
'redis_key':'add_statistics_hours_epi'
})
#执行日报统计,生成月报redis数据,定时,每天的0点3分执行
list_dict.append({
'jobid':'add_statistics_month_epi',
'trigger': dict(hour=0, minute=3),
'name':'add_statistics_month_epi',
'redis_key':'add_statistics_month_epi'
})
#执行月报统计,生成年报redis数据,#定时每个月1号0时10分计算一次
list_dict.append({
'jobid':'add_statistics_year_epi',
'trigger': dict(day=21, hour=00, minute=30),
'name':'add_statistics_year_epi',
'redis_key':'add_statistics_year_epi'
})
return list_dict
def job_dict():
list_dict = []
#------------------------能源管理-----------------------------------------------------------#
#执行日报统计,#定时每个小时的第几分钟执行
list_dict.append({
'jobid':'add_statistics_hours_epi',
'trigger': dict(second='*/1'),
'name':'add_statistics_hours_epi',
'redis_key':'add_statistics_hours_epi',
'time_type':0
})
#执行月报统计,生成月报redis数据,定时,每天的0点3分执行
list_dict.append({
'jobid':'add_statistics_month_epi',
'trigger': dict(second='*/2'),
'name':'add_statistics_month_epi',
'redis_key':'add_statistics_month_epi',
'time_type':1
})
#执行月报统计,生成月报redis数据,定时,每天的0点3分执行
list_dict.append({
'jobid':'add_statistics_year_epi',
'trigger': dict(second='*/3'),
'name':'add_statistics_year_epi',
'redis_key':'add_statistics_year_epi',
'time_type':2
})
return list_dict
#打印计划任务错误
def err_listener(events):
if events.code == EVENT_JOB_MISSED:
print("Job %s has missed." % str(events.job_id))
#添加计划任务
def add_job(scheduler,list_dict):
for job_dict in list_dict :
print_msg = scheduler.add_job(job_dict)
print(print_msg)
#设备和能源管理
def method(job_dict):
#redis_set_act(job_dict)
# runCommond(job_dict)
print(job_dict['jobid'],'',job_dict['time_type'])
#print('Job ' + str(job_id) + ' begin! The time is: %s' % datetime.now())
#time.sleep(2)
#print('Job ' + str(job_id) + ' end! The time is: %s' % datetime.now())
#设备和能源管理
def method1(job_dict):
#redis_set_act(job_dict)
# runCommond(job_dict)
print(job_dict['jobid'],'',job_dict['time_type'])
#计划任务管理类
class JobManager(object):
def __init__(self):
#EVENT_JOB_ADDED = 128
#EVENT_JOB_REMOVED = 256
#EVENT_JOB_MODIFIED = 512
#EVENT_JOB_EXECUTED = 1024
#EVENT_JOB_ERROR = 2048
#EVENT_JOB_MISSED = 4096#
self. LISTENER_JOB = (EVENT_JOB_ADDED |
EVENT_JOB_REMOVED |
EVENT_JOB_MODIFIED |
EVENT_JOB_EXECUTED |
EVENT_JOB_ERROR |
EVENT_JOB_MISSED|
EVENT_JOB_MAX_INSTANCES)
self.jobstores = {
'default': MemoryJobStore(),
'default_test': MemoryJobStore()
}
self.executors = {
'default': ThreadPoolExecutor(1),
'processpool': ProcessPoolExecutor(4)
}
self.job_defaults = {
'coalesce': True,
'max_instances': 100,
'misfire_grace_time': 60
}
#实例化scheduler类,创建BackgroundScheduler
self.scheduler = BackgroundScheduler(jobstores=self.jobstores, executors=self.executors, job_defaults=self.job_defaults, timezone=utc)
self.jobs = {}
self.scheduler.add_listener(err_listener, self.LISTENER_JOB)
self.scheduler.start()
print('scheduler start at:',datetime.now())
#添加计划任务
def add_job(self, job_dict):
job_id = job_dict['jobid']
#trigger = dict(second='*/2')
trigger = job_dict['trigger']
Trigger = CronTrigger(**trigger)
job = self.scheduler.add_job(method, Trigger, id=job_id, args=[job_dict])
#print(trigger)
print_msg = "add_job {} successful!;next run at:{}".format(job_id ,job.next_run_time)
#print_msg = "add_job %s successful!" % job_id + "; next_run_time: " + str(job.next_run_time)
return print_msg
#添加计划任务
def add_job1(self, job_dict):
job_id = job_dict['jobid']
#trigger = dict(second='*/2')
trigger = job_dict['trigger']
Trigger = CronTrigger(**trigger)
job = self.scheduler.add_job(method1, Trigger, id=job_id, args=[job_dict])
#print(trigger)
print_msg = "add_job {} successful!;next run at:{}".format(job_id ,job.next_run_time)
#print_msg = "add_job %s successful!" % job_id + "; next_run_time: " + str(job.next_run_time)
return print_msg
#恢复任务
def resume_job(self, job_id):
self.scheduler.resume_job(job_id)
print_msg = "resume_job {} successful!;at:{}".format(job_id , datetime.now())
return print_msg
#删除任务
def remove_job(self, job_id):
self.scheduler.remove_job(job_id)
print_msg = "remove_job {} successful!;at:{}".format(job_id , datetime.now())
return print_msg
#暂停任务
def pause_job(self, job_id):
self.scheduler.pause_job(job_id)
print_msg = "pause_job {} successful!;at:{}".format(job_id , datetime.now())
return print_msg
#获取所有任务
def get_job(self, job_id):
return self.scheduler.get_job(job_id)
#获取所有任务
def get_jobs(self):
return self.scheduler.get_jobs()
if __name__ == "__main__":
my_scheduler = JobManager()
#设备和能源管理计划任务
#my_apscheduler.add_job(my_scheduler)
add_job(my_scheduler,job_dict())
#能耗采集计划任务
#my_apscheduler.add_job_addin(my_scheduler)
#my_websocket.ws_start()
try:
while True:
time.sleep(1)
except (KeyboardInterrupt, SystemExit):
my_scheduler.scheduler.shutdown()