最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)定時(shí)任務(wù)利器之a(chǎn)pscheduler使用詳解

 更新時(shí)間:2022年10月11日 14:52:01   作者:芥末拌飯  
在Python中,還可以用第三方包來(lái)管理定時(shí)任務(wù),比如celery、apscheduler。相對(duì)來(lái)說(shuō)apscheduler使用起來(lái)更簡(jiǎn)單一些,這里來(lái)介紹一下apscheduler的使用方法

前言

之前有介紹了用Linux crontab的方式來(lái)實(shí)現(xiàn)定時(shí)任務(wù),這是使用Linux內(nèi)置模塊來(lái)實(shí)現(xiàn)的。而在Python中,還可以用第三方包來(lái)管理定時(shí)任務(wù),比如celery、apscheduler。相對(duì)來(lái)說(shuō)apscheduler使用起來(lái)更簡(jiǎn)單一些,這里來(lái)介紹一下apscheduler的使用方法。

首先安裝起來(lái)很簡(jiǎn)單,運(yùn)行pip install apscheduler即可。

初識(shí)apscheduler

來(lái)個(gè)簡(jiǎn)單的例子看看apscheduler是如何使用的。

#encoding:utf-8

from apscheduler.schedulers.blocking import BlockingScheduler
import datetime

def sch_test():
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('時(shí)間:{}, 測(cè)試apscheduler'.format(now))

task = BlockingScheduler()
task.add_job(func=sch_test, trigger='cron', second='*/10')
task.start()

上述例子很簡(jiǎn)單,我們首先要定義一個(gè)apscheduler的對(duì)象,然后add_job添加任務(wù),最后start開(kāi)啟任務(wù)就行了。

例子是每隔10秒運(yùn)行一次sch_test任務(wù),運(yùn)行結(jié)果如下:

時(shí)間:2022-10-08 15:16:30, 測(cè)試apscheduler
時(shí)間:2022-10-08 15:16:40, 測(cè)試apscheduler
時(shí)間:2022-10-08 15:16:50, 測(cè)試apscheduler
時(shí)間:2022-10-08 15:17:00, 測(cè)試apscheduler

如果我們要在執(zhí)行任務(wù)函數(shù)時(shí)攜帶參數(shù),只要在add_job函數(shù)中添加args就行,比如task.add_job(func=sch_test, args=('a'), trigger='cron', second='*/10')。

apscheduler有哪些模塊

上面例子中我們初步了解到如何使用apschedulerl了,接下來(lái)需要知道apscheduler的設(shè)計(jì)框架。apscheduler有四個(gè)主要模塊,分別是:觸發(fā)器triggers、任務(wù)存儲(chǔ)器job_stores執(zhí)行器executors、調(diào)度器schedulers

1. 觸發(fā)器triggers:

觸發(fā)器指的是任務(wù)指定的觸發(fā)方式,例子中我們用的是“cron”方式。我們可以選擇cron、date、interval中的一個(gè)。

1.cron表示的是定時(shí)任務(wù),類(lèi)似linux crontab,在指定的時(shí)間觸發(fā)。

可用參數(shù)如下:

參數(shù)釋義
year年份(4位數(shù),如2022)
month月份(1-12)
day一個(gè)月的第幾天(1-31)
week一年的第幾周(1-53)
day_of_week一星期的第幾天(0-6)
hour小時(shí)
minute分鐘
second
start_date開(kāi)始時(shí)間
end_date結(jié)束時(shí)間
timezone時(shí)區(qū)
jitter觸發(fā)的誤差時(shí)間

除此之外,我們還可用表達(dá)式類(lèi)型去設(shè)置cron。比如常用的有:

表達(dá)式釋義
*每個(gè)值都觸發(fā)
*/n每隔n觸發(fā)一次
a-b在a-b內(nèi)任何時(shí)間都觸發(fā)
a,b,c分別在a,b,c時(shí)間觸發(fā)

使用方法示例,在每天7點(diǎn)20分執(zhí)行一次:

task.add_job(func=sch_test, args=('定時(shí)任務(wù)',), trigger='cron',

hour='7', minute='20')

2.date表示具體到某個(gè)時(shí)間的一次性任務(wù);

使用方法示例:

# 使用run_date指定運(yùn)行時(shí)間
task.add_job(func='sch_test', trigger='date', run_date=datetime.datetime(2022 ,10 , 8, 16, 1, 30))
# 或者用next_run_time
task.add_job(func=sch_test,trigger='date', next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=3))

3.interval表示的是循環(huán)任務(wù),指定一個(gè)間隔時(shí)間,每過(guò)間隔時(shí)間執(zhí)行一次。

interval可設(shè)置如下的參數(shù):

參數(shù)釋義
weeks
days一個(gè)月的第幾天
hours小時(shí)
minutes分鐘
seconds
start_date間隔觸發(fā)的開(kāi)始時(shí)間
end_date間隔觸發(fā)的結(jié)束時(shí)間
jitter觸發(fā)的時(shí)間誤差

使用方法示例,每隔3秒執(zhí)行一次sch_test任務(wù):

task.add_job(func=sch_test, args=('循環(huán)任務(wù)',), trigger='interval', seconds=3)

來(lái)個(gè)例子把3種觸發(fā)器都使用一遍:

# encoding:utf-8
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime

def sch_test(job_type):
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('時(shí)間:{}, {}測(cè)試apscheduler'.format(now, job_type))

task = BlockingScheduler()
task.add_job(func=sch_test, args=('一次性任務(wù)',),trigger='date', next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=3))
task.add_job(func=sch_test, args=('定時(shí)任務(wù)',), trigger='cron', second='*/5')
task.add_job(func=sch_test, args=('循環(huán)任務(wù)',), trigger='interval', seconds=3)
task.start()

打印部分結(jié)果:

時(shí)間:2022-10-08 15:45:49, 一次性任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:49, 循環(huán)任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:50, 定時(shí)任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:52, 循環(huán)任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:55, 定時(shí)任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:55, 循環(huán)任務(wù)測(cè)試apscheduler
時(shí)間:2022-10-08 15:45:58, 循環(huán)任務(wù)測(cè)試apscheduler

通過(guò)代碼示例和結(jié)果展示,我們可清晰的知道不同觸發(fā)器的使用區(qū)別。

2. 任務(wù)存儲(chǔ)器job_stores

顧名思義,任務(wù)存儲(chǔ)器是存儲(chǔ)任務(wù)的地方,默認(rèn)都是存儲(chǔ)在內(nèi)存中。我們也可自定義存儲(chǔ)方式,比如將任務(wù)存到mysql中。這里有以下幾種選擇:

存儲(chǔ)器類(lèi)型釋義
MemoryJobStore任務(wù)存儲(chǔ)在內(nèi)存中
SQLAlchemyJobStore使用sqlalchemy作為存儲(chǔ)方式,存儲(chǔ)在數(shù)據(jù)庫(kù)
MongoDBJobStore存儲(chǔ)在mongodb中
RedisJobStore存儲(chǔ)在redis中

通常默認(rèn)存儲(chǔ)在內(nèi)存即可,但若程序故障重啟的話,會(huì)重新拉取任務(wù)運(yùn)行了,如果你對(duì)任務(wù)的執(zhí)行要求高,那么可以選擇其他的存儲(chǔ)器。

使用SQLAlchemyJobStore存儲(chǔ)器示例:

from apscheduler.schedulers.blocking import BlockingScheduler

def sch_test(job_type):
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('時(shí)間:{}, {}測(cè)試apscheduler'.format(now, job_type))

sched = BlockingScheduler()
# 使用mysql存儲(chǔ)任務(wù)
sql_url = 'mysql+pymysql://root:root@localhost:3306/db_name?charset=utf8'
sched.add_jobstore('sqlalchemy',url=sql_url)
# 添加任務(wù)
sched.add_job(func=sch_test, args=('定時(shí)任務(wù)',), trigger='cron', second='*/5')
sched.start()

3. 執(zhí)行器executors

執(zhí)行器的功能就是將任務(wù)放到線程池或進(jìn)程池中運(yùn)行。有以下幾種選擇:

執(zhí)行器類(lèi)型釋義
ThreadPoolExecutor線程池執(zhí)行器
ProcessPoolExecutor進(jìn)程池執(zhí)行器
GeventExecutorGevent 程序執(zhí)行器
TornadoExecutorTornado 程序執(zhí)行器
TwistedExecutorTwisted 程序執(zhí)行器
AsyncIOExecutorasyncio 程序執(zhí)行器

默認(rèn)是ThreadPoolExecutor, 常用的也就是第線程和進(jìn)程池執(zhí)行器。如果應(yīng)用是CPU密集型操作,可用ProcessPoolExecutor來(lái)執(zhí)行。

4. 調(diào)度器schedulers

調(diào)度器屬于apscheduler的核心,它扮演著統(tǒng)籌整個(gè)apscheduler系統(tǒng)的角色,存儲(chǔ)器、執(zhí)行器、觸發(fā)器在它的調(diào)度下正常運(yùn)行。調(diào)度器有以下幾個(gè):

調(diào)度器使用場(chǎng)景
BlockingScheduler當(dāng)調(diào)度器是你應(yīng)用中唯一要運(yùn)行的,start開(kāi)啟后會(huì)阻塞
BackgroundScheduler適用于調(diào)度程序在應(yīng)用程序的后臺(tái)運(yùn)行,start開(kāi)啟后不會(huì)阻塞
AsyncIOScheduler當(dāng)程序使用了asyncio的異步框架時(shí)使用。
GeventScheduler當(dāng)程序用了Tornado的時(shí)候用
TwistedScheduler當(dāng)程序用了Twisted的時(shí)候用
QtScheduler當(dāng)應(yīng)用是QT應(yīng)用的時(shí)候用

不是特定場(chǎng)景下,我們最常用的是BlockingScheduler調(diào)度器。

異常監(jiān)聽(tīng)

定時(shí)任務(wù)在運(yùn)行時(shí),若出現(xiàn)錯(cuò)誤,需要設(shè)置監(jiān)聽(tīng)機(jī)制,我們通常結(jié)合logging模塊記錄錯(cuò)誤信息。

使用示例:

from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
from apscheduler.events import EVENT_JOB_EXECUTED , EVENT_JOB_ERROR
import logging

# logging日志配置打印格式及保存位置
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    filename='sche.log',
                    filemode='a')

def log_listen(event):
	if event.exception :
		print ( '任務(wù)出錯(cuò),報(bào)錯(cuò)信息:{}'.format(event.exception))
	else:
		print ( '任務(wù)正常運(yùn)行...' )

def sch_test(job_type):
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('時(shí)間:{}, {}測(cè)試apscheduler'.format(now, job_type))
    print(1/0)

sched = BlockingScheduler()
# 使用mysql存儲(chǔ)任務(wù)
sql_url = 'mysql+pymysql://root:root@localhost:3306/db?charset=utf8'
sched.add_jobstore('sqlalchemy',url=sql_url)
# 添加任務(wù)
sched.add_job(func=sch_test, args=('定時(shí)任務(wù)',), trigger='cron', second='*/5')

# 配置任務(wù)執(zhí)行完成及錯(cuò)誤時(shí)的監(jiān)聽(tīng)
sched.add_listener(log_listen, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
# 配置日志監(jiān)聽(tīng)
sched._logger = logging

sched.start()

apscheduler的封裝使用

上面介紹了apscheduler框架的主要模塊,我們基本能掌握怎樣使用apscheduler了。下面就來(lái)封裝一下apscheduler吧,以后要用直接在這份代碼上修改就行了。

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.events import EVENT_JOB_EXECUTED , EVENT_JOB_ERROR
import logging
import logging.handlers
import os
import datetime


class LoggerUtils():
    def init_logger(self, logger_name):
        # 日志格式
        formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
        log_obj = logging.getLogger(logger_name)
        log_obj.setLevel(logging.INFO)
        # 設(shè)置log存儲(chǔ)位置
        path = '/data/logs/'
        filename = '{}{}.log'.format(path, logger_name)
        if not os.path.exists(path):
            os.makedirs(path)
        # 設(shè)置日志按照時(shí)間分割
        timeHandler = logging.handlers.TimedRotatingFileHandler(
           filename,
           when='D',  # 按照什么維度切割, S:秒,M:分,H:小時(shí),D:天,W:周
           interval=1, # 多少天切割一次
           backupCount=10  # 保留幾天
        )
        timeHandler.setLevel(logging.INFO)
        timeHandler.setFormatter(formatter)
        log_obj.addHandler(timeHandler)
        return log_obj


class Scheduler(LoggerUtils):
    def __init__(self):
        # 執(zhí)行器設(shè)置
        executors = {
            'default': ThreadPoolExecutor(10),  # 設(shè)置一個(gè)名為“default”的ThreadPoolExecutor,其worker值為10
            'processpool': ProcessPoolExecutor(5)  # 設(shè)置一個(gè)名為“processpool”的ProcessPoolExecutor,其worker值為5
        }
        self.scheduler = BlockingScheduler(timezone="Asia/Shanghai", executors=executors)
        # 存儲(chǔ)器設(shè)置
        # 這里使用sqlalchemy存儲(chǔ)器,將任務(wù)存儲(chǔ)在mysql
        sql_url = 'mysql+pymysql://root:root@localhost:3306/db?charset=utf8'
        self.scheduler.add_jobstore('sqlalchemy',url=sql_url)

        def log_listen(event):
            if event.exception:
                # 日志記錄
                self.scheduler._logger.error(event.traceback)
    
        # 配置任務(wù)執(zhí)行完成及錯(cuò)誤時(shí)的監(jiān)聽(tīng)
        self.scheduler.add_listener(log_listen, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
        # 配置日志監(jiān)聽(tīng)
        self.scheduler._logger = self.init_logger('sche_test')

    def add_job(self, *args, **kwargs):
        """添加任務(wù)"""
        self.scheduler.add_job(*args, **kwargs)

    def start(self):
        """開(kāi)啟任務(wù)"""
        self.scheduler.start()

# 測(cè)試任務(wù)
def sch_test(job_type):
    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('時(shí)間:{}, {}測(cè)試apscheduler'.format(now, job_type))
    print(1/0)


# 添加任務(wù),開(kāi)啟任務(wù)
sched = Scheduler()
# 添加任務(wù)
sched.add_job(func=sch_test, args=('定時(shí)任務(wù)',), trigger='cron', second='*/5')
# 開(kāi)啟任務(wù)
sched.start()

小結(jié)

這篇文章介紹了Python實(shí)現(xiàn)定時(shí)任務(wù)的又一利器apscheduler,通過(guò)簡(jiǎn)單例子及apscheduler框架的主要模塊分解,我們可以根據(jù)實(shí)際需求配置好模塊信息,再結(jié)合logging模塊,我們可以實(shí)時(shí)監(jiān)控到定時(shí)任務(wù)的運(yùn)行情況。

以上就是Python實(shí)現(xiàn)定時(shí)任務(wù)利器之a(chǎn)pscheduler使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Python apscheduler定時(shí)任務(wù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python解決%matplotlib inline標(biāo)紅底報(bào)錯(cuò)問(wèn)題

    Python解決%matplotlib inline標(biāo)紅底報(bào)錯(cuò)問(wèn)題

    在使用非Jupyter環(huán)境如Spyder或PyCharm時(shí),%matplotlib inline會(huì)因?yàn)槭荍upyter特有的魔法命令而導(dǎo)致報(bào)錯(cuò),這條命令是用于Jupyter Notebook或Jupyter Qt Console中,主要作用是將matplotlib的圖表直接嵌入到Notebook中顯示
    2024-09-09
  • django框架forms組件用法實(shí)例詳解

    django框架forms組件用法實(shí)例詳解

    這篇文章主要介紹了django框架forms組件用法,結(jié)合實(shí)例形式詳細(xì)分析了Django框架forms組件源碼及常用操作方法與使用注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • python激活虛擬環(huán)境(venv)的實(shí)現(xiàn)

    python激活虛擬環(huán)境(venv)的實(shí)現(xiàn)

    本文主要介紹了python激活虛擬環(huán)境(venv)的實(shí)現(xiàn),包括修改PATH環(huán)境變量、設(shè)置VIRTUAL_ENV變量、修改終端提示符、使用虛擬環(huán)境中的python和pip、加載虛擬環(huán)境的依賴等操作,感興趣的可以了解一下
    2025-05-05
  • Python中functools模塊的常用函數(shù)解析

    Python中functools模塊的常用函數(shù)解析

    這篇文章主要介紹了Python中functools模塊的常用函數(shù)解析,分別講解了partial、update_wrapper、wraps、total_ordering的用法,需要的朋友可以參考下
    2016-06-06
  • python中dir()與__dict__屬性的區(qū)別淺析

    python中dir()與__dict__屬性的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于python中dir()與__dict__屬性的區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Python實(shí)現(xiàn)曲線擬合操作示例【基于numpy,scipy,matplotlib庫(kù)】

    Python實(shí)現(xiàn)曲線擬合操作示例【基于numpy,scipy,matplotlib庫(kù)】

    這篇文章主要介紹了Python實(shí)現(xiàn)曲線擬合操作,結(jié)合實(shí)例形式分析了Python基于numpy,scipy,matplotlib庫(kù)讀取csv數(shù)據(jù)、計(jì)算曲線擬合及圖形繪制相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • python numpy元素的區(qū)間查找方法

    python numpy元素的區(qū)間查找方法

    今天小編就為大家分享一篇python numpy元素的區(qū)間查找方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Python 中將值附加到集合的操作方法

    Python 中將值附加到集合的操作方法

    這篇文章主要介紹了Python 中將值附加到集合的操作方法,通過(guò)使用 add() 方法或 update() 方法,你可以向 Python 中的集合中添加元素,在添加元素時(shí),需要注意不允許重復(fù)元素和集合是無(wú)序的,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Python學(xué)習(xí)筆記整理3之輸入輸出、python eval函數(shù)

    Python學(xué)習(xí)筆記整理3之輸入輸出、python eval函數(shù)

    這篇文章主要介紹了Python學(xué)習(xí)筆記整理3之輸入輸出、python eval函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • python pow函數(shù)的底層實(shí)現(xiàn)原理介紹

    python pow函數(shù)的底層實(shí)現(xiàn)原理介紹

    這篇文章主要介紹了python pow函數(shù)的底層實(shí)現(xiàn)原理介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03

最新評(píng)論

中西区| 铜山县| 嘉黎县| 扎赉特旗| 新蔡县| 庆安县| 顺昌县| 东乌珠穆沁旗| 吉隆县| 平武县| 辽中县| 惠安县| 阜新| 日照市| 红桥区| 五指山市| 泽库县| 华容县| 工布江达县| 祁东县| 怀来县| 乌兰浩特市| 平度市| 锦屏县| 石河子市| 高邮市| 嘉荫县| 定襄县| 鄂尔多斯市| 大丰市| 凌源市| 无极县| 苗栗县| 谢通门县| 阳高县| 镇坪县| 东乡| 大新县| 南昌县| 肥东县| 商都县|