python中实现定时任务的几种方案

目录

  • while True: + sleep()
  • Timeloop库
  • threading.Timer
  • sched模块
  • schedule模块
  • APScheduler框架
  • Celery框架
  • 数据流工具Apache Airflow
    • 概述
    • Airflow 核心概念
    • Airflow 的架构

总结以下几种方案实现定时任务,可根据不同需求去使用不同方案。

while True: + sleep()

利用while True的死循环,加上 sleep()函数让其暂停一段时间,达到每隔一段时间执行特定任务的目的。

比较简单,例子如下:

import datetime
import timedef time_printer():now = datetime.datetime.now()ts = now.strftime('%Y-%m-%d %H:%M:%S')print('do func time :', ts)def loop_monitor():while True:time_printer()time.sleep(5)if __name__ == "__main__":loop_monitor()

主要缺点:

  • 只能设定间隔,不能指定具体的时间
  • sleep 是一个阻塞函数,也就是说 sleep 这一段时间,程序什么也不能操作。

Timeloop库

Timeloop是一个库,可用于运行多周期任务。

Timeloop内部维护了一个任务列表jobs,用来管理所有任务。

可以使用装饰器标记任务,这样就会把任务加到任务列表jobs中,使用start方法启动任务列表重的所有任务。

示例如下:

import time
from timeloop import Timeloop
from datetime import timedeltatl = Timeloop()@tl.job(interval=timedelta(seconds=2))
def sample_job_every_2s():print("2s job current time : {}".format(time.ctime()))if __name__ == "__main__":tl.start(block=True)

运行后打印如下:

[2023-10-02 09:48:41,926] [timeloop] [INFO] Starting Timeloop..
[2023-10-02 09:48:41,926] [timeloop] [INFO] Registered job <function sample_job_every_2s at 0x7fc3d022d0d0>
[2023-10-02 09:48:41,926] [timeloop] [INFO] Timeloop now started. Jobs will run based on the interval set
2s job current time : Mon Oct  2 09:48:43 2023
2s job current time : Mon Oct  2 09:48:45 2023
2s job current time : Mon Oct  2 09:48:47 2023

同时Timeloop还有个stop方法,可以用来暂停所有任务。

threading.Timer

threading 模块中的 Timer 是一个非阻塞函数,比 sleep 稍好一点,timer最基本理解就是定时器,我们可以启动多个定时任务,这些定时器任务是异步执行,所以不存在等待顺序执行问题。

主要有如下方法:

方法说明
Timer(interval, function, args=None, kwargs=None)创建定时器
cancel()取消定时器
start()使用线程方式执行
join(self, timeout=None)主线程等待线程执行结束

示例:

import datetimefrom threading import Timerdef time_printer():now = datetime.datetime.now()ts = now.strftime('%Y-%m-%d %H:%M:%S')print('do func time :', ts)# 注意 Timer 只能执行一次,这里需要循环调用,否则只能执行一次loop_monitor()def loop_monitor():t = Timer(5, time_printer)t.start()if __name__ == "__main__":loop_monitor()

sched模块

sched模块实现了一个通用事件调度器,在调度器类使用一个延迟函数等待特定的时间,执行任务。同时支持多线程应用程序,在每个任务执行后会立刻调用延时函数,以确保其他线程也能执行。

class sched.scheduler(timefunc, delayfunc)这个类定义了调度事件的通用接口,它需要外部传入两个参数,timefunc是一个没有参数的返回时间类型数字的函数(常用使用的如time模块里面的time),delayfunc应该是一个需要一个参数来调用、与timefunc的输出兼容、并且作用为延迟多个时间单位的函数(常用的如time模块的sleep)。

import datetime
import time
import scheddef time_printer():now = datetime.datetime.now()ts = now.strftime('%Y-%m-%d %H:%M:%S')print('do func time :', ts)loop_monitor()def loop_monitor():s = sched.scheduler(time.time, time.sleep)  # 生成调度器s.enter(5, 1, time_printer, ())s.run()if __name__ == "__main__":loop_monitor()

scheduler对象主要方法:

enter(delay, priority, action, argument),安排一个事件来延迟delay个时间单位。
cancel(event):从队列中删除事件。如果事件不是当前队列中的事件,则该方法将跑出一个ValueError。
run():运行所有预定的事件。这个函数将等待(使用传递给构造函数的delayfunc()函数),然后执行事件,直到不再有预定的事件。
比threading.Timer更好,不需要循环调用。

schedule模块

schedule是一个第三方轻量级的任务调度模块,可以按照秒,分,小时,日期或者自定义事件执行时间。schedule允许用户使用简单、人性化的语法以预定的时间间隔定期运行Python函数(或其它可调用函数)。

示例:

import schedule
import timedef job():print("I'm working...")
schedule.every(10).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)while True:schedule.run_pending()time.sleep(1)

也可以通过 @repeat() 装饰静态方法:

import time
from schedule import every, repeat, run_pending@repeat(every().second)
def job():print('working...')while True:run_pending()time.sleep(1)

传递参数:

import scheduledef greet(name):print('Hello', name)
schedule.every(2).seconds.do(greet, name='Alice')
schedule.every(4).seconds.do(greet, name='Bob')while True:schedule.run_pending()

装饰器同样能传递参数:

from schedule import every, repeat, run_pending@repeat(every().second, 'World')
@repeat(every().minute, 'Mars')
def hello(planet):print('Hello', planet)while True:run_pending()

取消任务:

import schedulei = 0
def some_task():global ii += 1print(i)if i == 10:schedule.cancel_job(job)print('cancel job')exit(0)
job = schedule.every().second.do(some_task)while True:schedule.run_pending()

运行一次任务:

import time
import scheduledef job_that_executes_once():print('Hello')return schedule.CancelJobschedule.every().minute.at(':34').do(job_that_executes_once)
while True:schedule.run_pending()time.sleep(1)

根据标签检索任务:

# 检索所有任务:schedule.get_jobs()
import scheduledef greet(name):print('Hello {}'.format(name))schedule.every().day.do(greet, 'Andrea').tag('daily-tasks', 'friend')
schedule.every().hour.do(greet, 'John').tag('hourly-tasks', 'friend')
schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer')
schedule.every().day.do(greet, 'Derek').tag('daily-tasks', 'guest')friends = schedule.get_jobs('friend')
print(friends)

根据标签取消任务:

# 取消所有任务:schedule.clear()
import scheduledef greet(name):print('Hello {}'.format(name))if name == 'Cancel':schedule.clear('second-tasks')print('cancel second-tasks')schedule.every().second.do(greet, 'Andrea').tag('second-tasks', 'friend')
schedule.every().second.do(greet, 'John').tag('second-tasks', 'friend')
schedule.every().hour.do(greet, 'Monica').tag('hourly-tasks', 'customer')
schedule.every(5).seconds.do(greet, 'Cancel').tag('daily-tasks', 'guest')while True:schedule.run_pending()

运行任务到某时间:

import schedule
from datetime import datetime, timedelta, timedef job():print('working...')schedule.every().second.until('23:59').do(job)  # 今天23:59停止
schedule.every().second.until('2030-01-01 18:30').do(job)  # 2030-01-01 18:30停止
schedule.every().second.until(timedelta(hours=8)).do(job)  # 8小时后停止
schedule.every().second.until(time(23, 59, 59)).do(job)  # 今天23:59:59停止
schedule.every().second.until(datetime(2030, 1, 1, 18, 30, 0)).do(job)  # 2030-01-01 18:30停止while True:schedule.run_pending()

马上运行所有任务(主要用于测试):

import scheduledef job():print('working...')def job1():print('Hello...')schedule.every().monday.at('12:40').do(job)
schedule.every().tuesday.at('16:40').do(job1)
schedule.run_all()
schedule.run_all(delay_seconds=3)  # 任务间延迟3秒

并行运行:使用 Python 内置队列实现:

import threading
import time
import scheduledef job1():print("I'm running on thread %s" % threading.current_thread())def job2():print("I'm running on thread %s" % threading.current_thread())def job3():print("I'm running on thread %s" % threading.current_thread())def run_threaded(job_func):job_thread = threading.Thread(target=job_func)job_thread.start()schedule.every(10).seconds.do(run_threaded, job1)
schedule.every(10).seconds.do(run_threaded, job2)
schedule.every(10).seconds.do(run_threaded, job3)while True:schedule.run_pending()time.sleep(1)

APScheduler框架

APScheduler(advanceded python scheduler)基于Quartz的一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便。提供了基于日期、固定时间间隔以及crontab类型的任务,并且可以持久化任务。基于这些功能,我们可以很方便的实现一个Python定时任务系统。

具体使用参考文章:APScheduler框架使用

Celery框架

Celery是一个简单,灵活,可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需的工具, 也可用于任务调度。Celery 的配置比较麻烦,如果你只是需要一个轻量级的调度工具,Celery 不会是一个好选择。

Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。通常使用它来实现异步任务(async task)和定时任务(crontab)。异步任务比如是发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作 ,定时任务是需要在特定时间执行的任务。

具体使用参考:

Celery使用:优秀的python异步任务框架

Django(21):使用Celery任务框架

数据流工具Apache Airflow

概述

Apache Airflow 是Airbnb开源的一款数据流程工具,目前是Apache孵化项目。以非常灵活的方式来支持数据的ETL过程,同时还支持非常多的插件来完成诸如HDFS监控、邮件通知等功能。Airflow支持单机和分布式两种模式,支持Master-Slave模式,支持Mesos等资源调度,有非常好的扩展性。被大量公司采用。

Airflow使用Python开发,它通过DAGs(Directed Acyclic Graph, 有向无环图)来表达一个工作流中所要执行的任务,以及任务之间的关系和依赖。比如,如下的工作流中,任务T1执行完成,T2和T3才能开始执行,T2和T3都执行完成,T4才能开始执行。

在这里插入图片描述
Airflow提供了各种Operator实现,可以完成各种任务实现:

  • BashOperator – 执行 bash 命令或脚本。
  • SSHOperator – 执行远程 bash 命令或脚本(原理同 paramiko 模块)。
  • PythonOperator – 执行 Python 函数。
  • EmailOperator – 发送 Email。
  • HTTPOperator – 发送一个 HTTP 请求。
  • MySqlOperator, SqliteOperator, PostgresOperator, MsSqlOperator, OracleOperator, JdbcOperator, 等,执行 SQL 任务。
  • DockerOperator, HiveOperator, S3FileTransferOperator, PrestoToMysqlOperator, SlackOperator…

除了以上这些 Operators 还可以方便的自定义 Operators 满足个性化的任务需求。

一些情况下,我们需要根据执行结果执行不同的任务,这样工作流会产生分支。如:

在这里插入图片描述

这种需求可以使用BranchPythonOperator来实现。

Airflow 核心概念

  1. DAGs:即有向无环图(Directed Acyclic Graph),将所有需要运行的tasks按照依赖关系组织起来,描述的是所有tasks执行顺序。
  2. Operators:可以简单理解为一个class,描述了DAG中某个的task具体要做的事。其中,airflow内置了很多operators,如BashOperator 执行一个bash 命令,PythonOperator 调用任意的Python 函数,EmailOperator 用于发送邮件,HTTPOperator 用于发送HTTP请求, SqlOperator 用于执行SQL命令等等,同时,用户可以自定义Operator,这给用户提供了极大的便利性。
  3. Tasks:Task 是 Operator的一个实例,也就是DAGs中的一个node。
  4. Task Instance:task的一次运行。Web 界面中可以看到task instance 有自己的状态,包括”running”, “success”, “failed”, “skipped”, “up for retry”等。
  5. Task Relationships:DAGs中的不同Tasks之间可以有依赖关系,如 Task1 >> Task2,表明Task2依赖于Task2了。通过将DAGs和Operators结合起来,用户就可以创建各种复杂的 工作流(workflow)。

Airflow 的架构

在一个可扩展的生产环境中,Airflow 含有以下组件:

  1. 元数据库:这个数据库存储有关任务状态的信息。
  2. 调度器:Scheduler 是一种使用 DAG 定义结合元数据中的任务状态来决定哪些任务需要被执行以及任务执行优先级的过程。调度器通常作为服务运行。
  3. 执行器:Executor 是一个消息队列进程,它被绑定到调度器中,用于确定实际执行每个任务计划的工作进程。有不同类型的执行器,每个执行器都使用一个指定工作进程的类来执行任务。例如,LocalExecutor 使用与调度器进程在同一台机器上运行的并行进程执行任务。其他像 CeleryExecutor 的执行器使用存在于独立的工作机器集群中的工作进程执行任务。
  4. Workers:这些是实际执行任务逻辑的进程,由正在使用的执行器确定。

在这里插入图片描述
Worker的具体实现由配置文件中的executor来指定,airflow支持多种Executor:

  1. SequentialExecutor: 单进程顺序执行,一般只用来测试
  2. LocalExecutor: 本地多进程执行
  3. CeleryExecutor: 使用Celery进行分布式任务调度
  4. DaskExecutor:使用Dask进行分布式任务调度
  5. KubernetesExecutor: 1.10.0新增, 创建临时POD执行每次任务

生产环境一般使用CeleryExecutor和KubernetesExecutor。

使用CeleryExecutor的架构如图:

在这里插入图片描述
使用KubernetesExecutor的架构如图:

在这里插入图片描述

参考:

https://mp.weixin.qq.com/s/dzA9xGoho50WK_-80hzelg

https://zhuanlan.zhihu.com/p/448847300

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148371.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Pytorch目标分类深度学习自定义数据集训练

目录 一&#xff0c;Pytorch简介&#xff1b; 二&#xff0c;环境配置&#xff1b; 三&#xff0c;自定义数据集&#xff1b; 四&#xff0c;模型训练&#xff1b; 五&#xff0c;模型验证&#xff1b; 一&#xff0c;Pytorch简介&#xff1b; PyTorch是一个开源的Python机…

【4】c++设计模式——>UML表示类之间的聚合关系

聚合关系表示整体与部分的关系&#xff0c;在聚合关系中&#xff0c;成员对象时整体的一部分&#xff0c;但是成员对象可以脱离整体对象独立存在&#xff0c;当整体被析构销毁的时候&#xff0c;组成整体的这些子对象是不会被销毁的&#xff0c;是可以继续存活&#xff0c;并在…

Hono——一个小型,简单且超快的Edges Web框架

Hono - [炎]在日语中的意思是火焰&#x1f525; - 是一个小型&#xff0c;简单且超快的Edges Web框架。它适用于任何JavaScript运行时&#xff1a;Cloudflare Workers&#xff0c;Fastly ComputeEdge&#xff0c;Deno&#xff0c;Bun&#xff0c;Vercel&#xff0c;Netlify&…

机器学习 不均衡数据采样方法:imblearn 库的使用

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

CSS3与HTML5

box-sizing content-box&#xff1a;默认&#xff0c;宽高包不含边框和内边距 border-box&#xff1a;也叫怪异盒子&#xff0c;宽高包含边框和内边距 动画&#xff1a;移动translate&#xff0c;旋转、transform等等 走马灯&#xff1a;利用动画实现animation&#xff1a;from…

【C++进阶(七)】仿函数深度剖析模板进阶讲解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 模板进阶 1. 前言2. 仿函数的概念3. 仿函数的实…

背包问题

目录 开端 01背包问题 AcWing 01背包问题 Luogu P2925干草出售 Luogu P1048采药 完全背包问题 AcWing 完全背包问题 Luogu P1853投资的最大效益 多重背包问题 AcWing 多重背包问题 I AcWing 多重背包问题 II Luogu P1776宝物筛选 混合背包问题 AcWing 混合背包问题…

3种等待方式,让你学会Selenium设置自动化等待测试脚本!

一、Selenium脚本为什么要设置等待方式&#xff1f;——即他的应用背景到底是什么 应用Selenium时&#xff0c;浏览器加载过程中无法立即显示对应的页面元素从而无法进行元素操作&#xff0c;需设置一定的等待时间去等待元素的出现。&#xff08;简单来说&#xff0c;就是设置…

Unity实现设计模式——状态模式

Unity实现设计模式——状态模式 状态模式最核心的设计思路就是将对象的状态抽象出一个接口&#xff0c;然后根据它的不同状态封装其行为&#xff0c;这样就可以实现状态和行为的绑定&#xff0c;最终实现对象和状态的有效解耦。 在实际开发中一般用到FSM有限状态机的实现&…

python二次开发CATIA:文字轮廓草图

CATIA V5 版本的草图中&#xff0c;并没有文字轮廓的创建命令。通常的做法是&#xff0c;再Drawing 文件中创建所需文本-->将 Drawing 文件另存为 dwg / dxf 格式-->打开另存的文件&#xff0c;文字已转为轮廓线条-->复制线条并粘贴到草图中。 本例中&#xff0c;基于…

day49数据库 索引 事务

一、索引 什么是索引&#xff1a;索引是数据库库中用来提高查询效率的技术&#xff0c;类似于目录 为什么要使用索引&#xff1a;如果不使用索引&#xff0c;数据会零散的保存在磁盘块中&#xff0c;查询数据需要遍历每一个磁盘块&#xff0c;直到找到数据为止&#xff0c;效率…

Python学习笔记之分支结构与循环结构

Python学习笔记之分支结构与循环结构 一、分支结构 使用关键字if、elif、else 练习1&#xff1a;使用分支结构实现分段函数求值 """分段函数求值""" x float(input("x "))if x > 1:y 3 * x - 5 elif x < -1:y 5 * x 3…

【数仓精品理论分析】能不能学大数据?

【数仓精品理论分析】能不能学大数据&#xff1f; 还能不能学大数据datapulse官网&#xff1a; 自身情况数据行业发展情况 还能不能学大数据 首先看到这个话题的时候&#xff0c;我是这样想的&#xff0c;能不能学大数据需要参考本人的自身情况【学历、年龄、决心、有没有矿或者…

12、Kubernetes中KubeProxy实现之iptables和ipvs

目录 一、概述 二、iptables 代理模式 三、iptables案例分析 四、ipvs案例分析 一、概述 iptables和ipvs其实都是依赖的一个共同的Linux内核模块&#xff1a;Netfilter。Netfilter是Linux 2.4.x引入的一个子系统&#xff0c;它作为一个通用的、抽象的框架&#xff0c;提供…

手机自动直播系统源码交付与代理加盟注意事项解析!

随着直播行业的不断发展&#xff0c;手机自动直播已经成为了人们生活中不可或缺的一部分。手机无人直播软件成了香饽饽&#xff0c;各类手机实景直播APP大批量涌现。因为创业和技术门槛低&#xff0c;市场需求高&#xff0c;所以成了最火热创业赛道。那么如果是不懂技术的人群&…

由Long类型引发的生产事故

事情原由 今天测试忽然在群里发了一个看似非常简单的线上问题&#xff0c;具体是&#xff1a;在后台通过订单编号(orderId)修改订单信息时&#xff0c;修改不成功 &#xff0c;修改前后的订单数据完全没有发生变化。第一眼看到这个问题的时候&#xff0c;我心想后台实现逻辑并不…

CSS 语法

CSS 实例 CSS 规则由两个主要的部分构成&#xff1a;选择器&#xff0c;以及一条或多条声明: 选择器通常是您需要改变样式的 HTML 元素。 每条声明由一个属性和一个值组成。 属性&#xff08;property&#xff09;是您希望设置的样式属性&#xff08;style attribute&#x…

IDEA 配置 Maven(解决依赖下载缓慢)

IDEA 配置 Maven&#xff08;解决依赖下载缓慢&#xff09; 这一篇主要介绍 Maven 的基本用法。等我之后学习到框架知识时&#xff0c;会完善此部分内容。 一、Maven 简介 Maven 是专门用于管理和构建 Java 项目的工具&#xff0c;Apache Maven 是一个项目管理和构建工具&#…

lenovo联想台式机 拯救者 刃7000-28ICBR(90KX)原装出厂Windows10系统镜像

LENOVO联想拯救者(90KX)原厂WIN10系统 下载链接&#xff1a;https://pan.baidu.com/s/1beocPJSmnFbY4Y_ZQM2djA?pwd4d1n 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大…

QT、C++实现地图导航系统(mapSystem)

文章目录 地图导航系统项目应用背景技术栈选择数据处理算法实现界面实现源码展示成果展示源码下载 &#xff08;免费&#xff09; 地图导航系统 项目应用背景 电子地图导航系统的主要目的是为用户提供精确、实时的导航和位置信息&#xff0c;以帮助他们在城市或地区内轻松找到…