APScheduler——Python定時任務框架

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()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章