python第三方庫系列之十三--定時任務apscheduler庫

來源:互聯網
上載者:User
        APScheduler是基於Quartz的一個Python定時任務架構,實現了Quartz的所有功能,使用起來十分方便。提供了基於日期、固定時間間隔以及crontab類型的任務,並且可以持久化任務。基於這些功能,我們可以很方便的實現一個python定時任務系統,寫python還是要比java舒服多了。

1. 定時任務例子

        APScheduler是進程內的調度器,可以定時觸發具體的函數,並且可以訪問應用的所有變數和函數。在web應用中通過APScheduler實現定時任務是很方便的。下面看例子:

from apscheduler.scheduler import Scheduler  schedudler = Scheduler(daemonic = False)  @schedudler.cron_schedule(second='*', day_of_week='0-4', hour='9-12,13-15')  def quote_send_sh_job():      print 'a simple cron job start at', datetime.datetime.now()    schedudler.start()  

        上面通過裝飾器定義了cron job,可以通過函數scheduler.add_cron_job添加,用裝飾器更方便。Scheduler建構函式中傳入daemonic參數,表示執行線程是非守護的,在Schduler的文檔中推薦使用非守護線程:(Jobs are always executed in non-daemonic threads.  )

        定時任務的三種方式:

        (1)simple date-based scheduling(定時任務,時間固定,執行一次)

from datetime import datefrom apscheduler.scheduler import Scheduler# Start the schedulersched = Scheduler()sched.start()# example: 需求:在 2013-1-4 13:14:21 列印 i love you</span>def my_job(text):   print text# Store the job in a variable in case we want to cancel it# 方法的第一個參數是需要執行的方法名,第二個參數是時間,第三個參數是需要執行的方法的參數列表job = sched.add_date_job(my_job, '2013-01-04 13:14:21', ['i love you'])</span>

        (2)Interval-based scheduling(每隔多長時間執行一次)

# example: 需求:每隔一個小時列印一次hello world</span>job = sched.add_interval_job(my_job,hour=1,['hellow world'])

        (3)cron-style scheduling(定時迴圈執行,比如每個月的幾號,或者每周幾,或者一年中的第幾周執行)

# 沒有設定時分秒預設為0,example: 需求: 每周一,三,五列印hello world(周日是0,周六是6)job = sched.add_cron_job(my_job,day-of-week='0,2,4',['hellow world'])

        更多參數挪步官網:https://apscheduler.readthedocs.org/en/v2.1.0/modules/scheduler.html

        在添加job時還有一個比較重要的參數max_instances,指定一個job的並發執行個體數,預設值是1。預設情況下,如果一個job準備執行,但是該job的前一個執行個體尚未執行完,則後一個job會失敗,可以通過這個參數來改變這種情況。

2. 儲存任務執行資訊

        APScheduler提供了jobstore用於儲存job的執行資訊,預設使用的是RAMJobStore,還提供了SQLAlchemyJobStore、ShelveJobStore和MongoDBJobStore。APScheduler允許同時使用多個jobstore,通過別名(alias)區分,在添加job時需要指定具體的jobstore的別名,否則使用的是別名是default的jobstore,即RAMJobStore。下面以MongoDBJobStore舉例說明。

import pymongo  from apscheduler.scheduler import Scheduler  from apscheduler.jobstores.mongodb_store import MongoDBJobStore  import time    sched = Scheduler(daemonic = False)    mongo = pymongo.Connection(host='127.0.0.1', port=27017)  store = MongoDBJobStore(connection=mongo)  sched.add_jobstore(store, 'mongo')        # 別名是mongo   @sched.cron_schedule(second='*', day_of_week='0-4', hour='9-12,13-15', jobstore='mongo')        # 向別名為mongo的jobstore添加job  def job():      print 'a job'      time.sleep(1)    sched.start()  

        注意start必須在添加job動作之後調用,否則會拋錯。預設會把job資訊儲存在apscheduler資料庫下的jobs表:

> db.jobs.findOne()  {          "_id" : ObjectId("502202d1443c1557fa8b8d66"),          "runs" : 20,          "name" : "job",          "misfire_grace_time" : 1,          "coalesce" : true,          "args" : BinData(0,"gAJdcQEu"),          "next_run_time" : ISODate("2012-08-08T14:10:46Z"),          "max_instances" : 1,          "max_runs" : null,          "trigger" : BinData(0,"xxx..."),          "func_ref" : "__main__:job",          "kwargs" : BinData(0,"gAJ9cQEu")  }  

        上面就是儲存的具體資訊。
3.異常處理

        當job拋出異常時,APScheduler會默默的把他吞掉,不提供任何提示,這不是一種好的實踐,我們必須知曉程式的任何差錯。APScheduler提供註冊listener,可以監聽一些事件,包括:job拋出異常、job沒有來得及執行等。

        看下面的例子,監聽異常和miss事件,這裡用logging模組列印日誌,logger.exception()可以列印出異常堆棧資訊。

def err_listener(ev):      err_logger = logging.getLogger('schedErrJob')      if ev.exception:          err_logger.exception('%s error.', str(ev.job))      else:          err_logger.info('%s miss', str(ev.job))    schedudler.add_listener(err_listener, apscheduler.events.EVENT_JOB_ERROR | apscheduler.events.EVENT_JOB_MISSED)  

        事件的屬性包括:

job – the job instance in questionscheduled_run_time – the time when the job was scheduled to be runretval – the return value of the successfully executed jobexception – the exception raised by the jobtraceback – the traceback object associated with the exception

        最後,需要注意一點當job不以daemon模式運行時,並且APScheduler也不是daemon的,那麼在關閉指令碼時,Ctrl + C是不奏效的,必須kill才可以。可以通過命令實現關閉指令碼:

ps axu | grep {指令碼名} | grep -v grep | awk '{print $2;}' | xargs kill  



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.