python定时任务apscheduler

本文介绍了apscheduler库中的两种调度器——BackgroundScheduler和BlockingScheduler。BackgroundScheduler是非阻塞的,适合在后台执行任务,不干扰主线程,需要手动启动。而BlockingScheduler则是阻塞式的,在主线程中执行任务,会阻止其他任务执行。文章还提供了示例代码展示如何使用这两种调度器进行任务定义和执行,并包含任务监听和管理的示例。
摘要由CSDN通过智能技术生成

一、BackgroundScheduler与BlockingScheduler区别

apscheduler库中的BackgroundSchedulerBlockingScheduler都是调度器类,用于在后台执行任务。它们之间的主要区别在于任务调度的方式以及对主线程的影响。

  1. BackgroundScheduler

    • BackgroundScheduler是一个非阻塞的调度器,适用于在后台执行任务而不阻塞主线程。
    • 它会创建一个后台线程来执行任务,这样主线程可以继续执行其他操作。
    • BackgroundScheduler需要手动启动调度器,并且需要调用start方法来开始任务调度。
    • 一旦调度器启动,它将根据预定的时间表自动触发任务的执行。
  2. BlockingScheduler

    • BlockingScheduler是一个阻塞的调度器,适用于在主线程中执行任务。
    • 它会在主线程中循环执行任务,直到调度器被关闭或程序退出。
    • BlockingScheduler会阻塞主线程,因此在使用它时需要注意,确保没有其他重要的任务被阻塞。
    • 要启动调度器,只需调用start方法即可。它将按照预定的时间表开始执行任务,并阻塞主线程。

二、示例

 python3.8示例

import os
import sys
import uuid

from datetime import datetime, timedelta

# 非阻塞调度器,适用于后台执行任务,不阻塞主进程
from apscheduler.events import EVENT_ALL
from apscheduler.schedulers.background import BackgroundScheduler
# 阻塞调度器,适用于在主线程中执行任务,会在主线程中循环执行任务
from apscheduler.schedulers.blocking import BlockingScheduler


"""
interval间隔执行,date定时执行,cron周期执行
"""

job_id = uuid.uuid4().hex
print(job_id)

# = = = = = = = = = = = = = = = = = = = = = 任务定义 = = = = = = = = = = = = = = = = = = = = =

def task1(params):
    print(f'执行任务1。。。,参数:{params}')

def task2(params):
    print(f'执行任务2。。。,参数:{params}')

def task3(params):
    print(f'执行任务3。。。,参数:{params}')

def task4(params):
    print(f'执行任务4。。。,参数:{params}')

def task5(params):
    print(f'执行任务5。。。,参数:{params}')

def task6(params):
    print(f'执行任务6。。。,参数:{params}')

def task8(params):
    print(f'执行任务8。。。,参数:{params}')
    # 故意抛出异常,因为除数不能为0
    print(1 / 0)



# = = = = = = = = = = = = = = = = = = = = = 应用示例 = = = = = = = = = = = = = = = = = = = = =
def easy_use():
    """
    简单使用
    :return:
    """
    # 实例化
    sched = BlockingScheduler()
    # sched = BackgroundScheduler()
    # 1. 间隔5秒(间隔设定,周/天/时/分/秒weeks、days、hours、minutes、seconds)
    """
    当 coalesce 设置为 True 时,如果任务的执行时间被错过(即到了该执行任务的时间,但由于前一个任    务实例仍在运行或其他原因导致任务未能及时启动),那么调度器将不会立即启动一个新的任务实例,而是会等待下一个触发时间点再执行。这样可以防止任务堆积和重复执行,确保在任务执行时间较长或调度器繁忙时,任务不会“堆积”起来。
    """
    sched.add_job(task1, 'interval', seconds=5, args=['间隔5秒执行'], id=job_id, name="测试任务1", coalesce=True)
    # 2. 固定时间执行,run_date参数:可以是date类型、datetime类型、文本类型
    sched.add_job(task2, 'date', run_date=datetime(2023, 7, 26, 17, 13, 0), args=['到2023-7-26 17:13执行'])
    sched.add_job(task3, 'date', run_date="2023-07-26 17:12:50", args=['到2023-07-26 17:12:00执行'])
    # 3. 在起始时间内,间隔执行
    sched.add_job(task4, 'interval', seconds=5, start_date="2023-07-26 17:16:50", end_date="2023-07-26 17:17:50" ,args=['起始时间内,间隔5秒执行'])
    # 4. cron触发器
    sched.add_job(task5, 'cron', second='0/5', args=['cron触发器,间隔5秒执行'])
    sched.add_job(task6, 'cron', hour='11', minute='0', second='0', args=['每天固定一个时间11:00:00执行'])
    # 5. 任务监听任务
    sched.add_job(task8, args=['执行一次,会出错'], next_run_time=datetime.now() + timedelta(seconds=10), id='123456')


    # 删除任务
    # sched.remove_job(sched.get_job(job_id).id)

    # 暂停任务
    sched.pause_job(sched.get_job(job_id).id)
    # 恢复任务
    sched.resume_job(sched.get_job(job_id).id)

    # 输出作业信息
    sched.print_jobs()
    # 获取任务列表
    print(sched.get_jobs())

    # 配置任务执行完成和任务错误的监听
    scheduler.add_listener(err_listener, mask=EVENT_ALL)
    sched.start()

    print("注册结束")


def advanced():
    """
    进阶,配置项
    :return:
    """

    # 导入线程池执行器
    from apscheduler.executors.pool import ThreadPoolExecutor
    # 导入sqlalchemy,使用MySQL数据库存储
    from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
    # 导入阻塞调度器
    from apscheduler.schedulers.blocking import BlockingScheduler
    # 导入cron表达式触发器
    from apscheduler.triggers.cron import CronTrigger
    # 导入生成随机数模块
    import random

    # 创建定时任务执行函数
    def task7(number):
        print("开始执行任务,传入的随机数为%s" % number)

    # 作业存储器配置 使用MySQL数据库存储
    # job_stores = {
    #     'default': {
    #         'type': 'sqlalchemy',
    #         'url': 'mysql://root:xxxx@127.0.0.1:3306/xxx?charset=utf8'
    #     }
    # }
    # 使用django的stores
    # from django_apscheduler.jobstores import DjangoJobStore
    # scheduler.add_jobstore(DjangoJobStore(), "default")


    # 执行器配置 使用线程池执行器,最大10个线程
    executors = {
        'default': ThreadPoolExecutor(10),
    }

    # Job相关配置,更多选项参见官方文档
    job_defaults = {
        # 1. 设置这个目的是,比如由于某个原因导致某个任务积攒了很多次没有执行(比如有一个任务是1分钟跑一次,但是系统原因断了5分钟),
        # 2. 如果 coalesce=True,那么下次恢复运行的时候,会只执行一次,而如果设置 coalesce=False,那么就不会合并,会5次全部执行,
        # 3. 也可以在每个job,add时,传参添加,这是统一配置
        'coalesce': False,
        # 同一个任务同一时间最多只能有3个实例在运行。
        # 比如一个10分钟的job,指定每分钟运行1次,如果max_instance=3,那么在第3~10分钟上,新的运行实例不会被执行,因为已经有3个实例在运行。
        'max_instances': 3
    }

    # 1. 实例化调度器,关键字配置
    scheduler = BlockingScheduler(
        # jobstores=job_stores,
        executors=executors,
        job_defaults=job_defaults,
        timezone='Asia/Shanghai'  # 指定时区
    )


    config = {
        # 作业存储器配置 使用MySQL数据库存储
        'apscheduler.jobstores.default': {
            'type': 'sqlalchemy',
            'url': 'mysql://root:123.com@127.0.0.1:3306/job?charset=utf8'
        },
        # 执行器配置 使用线程池执行器,最大10个线程
        'apscheduler.executors.default': {
            'class': 'apscheduler.executors.pool:ThreadPoolExecutor',
            'max_workers': '10'
        },
        # Job配置,为新任务关闭合并模式
        'apscheduler.job_defaults.coalesce': 'false',
        # Job配置,同一个任务同一时间最多只能有3个实例在运行
        'apscheduler.job_defaults.max_instances': '3',
        # Job配置,指定时区
        'apscheduler.timezone': 'Asia/Shanghai',
    }

    # 2. 实例化调度器,字典配置
    scheduler = BlockingScheduler(config)


# = = = = = = = = = = = = = = = = = = = = = 其他使用示例 = = = = = = = = = = = = = = = = = = = = =

def get_job_info():
    """
    根据job_id,获取job信息
    :return:
    """
    sched = BackgroundScheduler()
    print(sched.get_job(job_id).name)

def err_listener(event):
    job_id = str(event.job_id)
    print(job_id)
    print(event.exception)

# = = = = = = = = = = = = = = = = = = = = = 装饰器应用示例 = = = = = = = = = = = = = = = = = = = = =
# 装饰器,定时任务执行函数
scheduler = BlockingScheduler()
@scheduler.scheduled_job(trigger="interval", args=(1,), seconds=3)
def task7(number):
    print("开始执行任务,传入的参数是%s" % number)


if __name__ == '__main__':
    print("主进程...start...")
    easy_use()
    print("主进程...end...")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值