摘要:Python 有几种方法可以定时调度一个任务,这就是我们将在本文中学习的内容。

本文分享自华为云社区《Python中使用定时调度任务(Schedule Jobs)的5种方式)》,作者: Regan Yue 。

今天构建的大多数应用程序都需要某种方式的调度机制。轮询 API 或数据库、不断检查系统健康状况、将日志存档等是常见的例子。 Kubernetes和Apache Mesos等使用自动伸缩扩容技术(Auto-scaling)的软件需要检查部署的应用程序的状态,为此它们使用定期运行的存活探针(Liveness Probe)。调度任务需要与业务逻辑解耦,因此我们要使用解耦的执行队列,例如Redis队列。

Python 有几种方法可以定时调度一个任务,这就是我们将在本文中学习的内容。我将使用以下方式讨论调度任务:

  1. 简单循环 (Simple Loops)
  2. 简单循环但是使用了线程 (Simple Loops but Threaded)
  3. 调度库 (Schedule Library)
  4. Python Crontab
  5. RQ 调度器作为解耦队列 (RQ Scheduler as decoupled queues)

简单循环 Simple loops

使用简单循环来实现调度任务这是毫不费力的。使用无限运行的 while 循环定期调用函数可用于调度作业,但这不是最好的方法,不过它是很有效的。可以使用内置time模块的slleep()来延迟执行。不过这并不是大多数作业的调度方式,因为,它看起来很难看,而且与其他方法相比,它的可读性较差。

import time

def task():
print("Job Completed!")

while 1:
task()
time.sleep(10)

当涉及到每天早上 9:00 或每周三晚上 7:45 等这些日程安排时,事情就变得比较棘手了。

import datetime

def task():
print("Job Completed!")

while 1:
now = datetime.datetime.now()
# schedule at every wednesday,7:45 pm
if now.weekday == 3 and now.strftime("%H:%m") == "19:45":
task()
# sleep for 6 days
time.sleep(6 * 24 * 60 * 60)

这是我的第一时间想到的解决办法,不用谢!这种方法的一个问题是这里的逻辑是阻塞的,即一旦在 python 项目中发现这段代码,它就会卡在 while 1 循环中,从而阻塞其他代码的执行。

简单循环但是使用了线程Simple loops but threaded

线程是计算机科学中的一个概念。具有自己指令的小程序由进程执行并独立管理,这就可以解决我们第一种方法的阻塞情况,让我们看看怎么样。

import time
import threading

def task():
print("Job Completed!")

def schedule():
while 1:
task()
time.sleep(10)

# makes our logic non blocking
thread = threading.Thread(target=schedule)
thread.start()

线程启动后,其底层逻辑无法被主线程修改,因此我们可能需要添加资源,程序通过这些资源可以检查特定场景并根据它们执行逻辑。

定时调度库 Schedule Library

早些时候,我说使用 while 循环进行调度看起来很丑陋,调度库可以解决这个问题。

import schedule
import time

def task():
print("Job Executing!")

# for every n minutes
schedule.every(10).minutes.do(task)

# every hour
schedule.every().hour.do(task)

# every daya at specific time
schedule.every().day.at("10:30").do(task)

# schedule by name of day
schedule.every().monday.do(task)

# name of day with time
schedule.every().wednesday.at("13:15").do(task)

while True:
schedule.run_pending()
time.sleep(1)

正如您所见,通过这样我们可以毫不费力地创建多个调度计划。我特别喜欢创建作业的方式和方法链(Method Chaining),另一方面,这个片段有一个 while 循环,这意味着代码被阻塞,不过我相信你已经知道什么可以帮助我们解决这个问题。

Python Crontab

Liunx 中的 crontab 实用程序是一种易于使用且被广泛接受的调度解决方案。Python 库python-crontab提供了一个 API 来使用 Python 中的 CLI 工具。在crontab中,一个定时调度使用 unix-cron字符串格式(* * * * *)来描述,它是一组五个值的一条线,这表明当作业应该被执行时,python-crontab 将在文件中写入 crontab 的计划转换为写入编程方法。

from crontab import CronTab

cron = CronTab(user='root')

job = cron.new(command='my_script.sh')

job.hour.every(1)
cron.write()

python-crontab 不会自动保存计划,需要执行 write() 方法来保存计划。还有更多功能,我强烈建议您查看他们的文档。

RQ 调度器 RQ Scheduler

有些任务不能立即执行,因此我们需要根据 LIFO 或 FIFO 等队列系统创建任务队列并弹出任务。python-rq允许我们做到这一点,使用 Redis 作为代理来排队作业。新作业的条目存储为带有信息的哈希映射,例如created_at, enqueued_at, origin, data, description.

排队任务由名为 worker 的程序执行。workers 在 Redis 缓存中也有一个条目,负责将任务出列以及更新 Redis 中的任务状态。任务可以在需要时排队,但要安排它们,我们需要rq-scheduler。

from rq_scheduler import Scheduler

queue = Queue('circle', connection=Redis())
scheduler = Scheduler(queue=queue)

scheduler.schedule(
scheduled_time=datetime.utcnow(), # Time for first execution, in UTC timezone
func=func, # Function to be queued
args=[arg1, arg2], # Arguments passed into function when executed
kwargs={'foo': 'bar'}, # Keyword arguments passed into function when executed
interval=60, # Time before the function is called again, in seconds
repeat=None, # Repeat this number of times (None means repeat forever)
meta={'foo': 'bar'} # Arbitrary pickleable data on the job itself
)

RQ worker(RQ 工作器)必须在终端中单独启动或通过 python-rq 工作器启动。一旦任务被触发,就可以在工作终端中看到,在成功和失败场景中都可以使用单独的函数回调。

总结 Conclusion

还有一些用于调度的库,但在这里,我已经讨论了最常见的库。值得一提的是Celery,celery 的另一个优点是用户可以在多个代理之间进行选择。我很感激你读到最后。也可以看看我的其他文章。干杯!

翻译来源: https://python.plainenglish.io/5-ways-to-schedule-jobs-in-python-99de8a80f28e

点击关注,第一时间了解华为云新鲜技术~

5种Python使用定时调度任务的方式的更多相关文章

  1. 【Python】定时调度

    from datetime import datetime from apscheduler.schedulers.blocking import BlockingScheduler def tick ...

  2. Linux系统crontab定时调度Python脚本

    Linux系统crontab定时调度Python脚本 一.Python脚本随Linux开机自动运行 #Python脚本:/home/edgar/auto.py #用root权限编辑以下文件:/etc/ ...

  3. Python实现定时执行任务的三种方式简单示例

    本文实例讲述了Python实现定时执行任务的三种方式.分享给大家供大家参考,具体如下: 1.定时任务代码 import time,os,sched schedule = sched.scheduler ...

  4. 定时调度框架Quartz随笔

    最近项目中的定时批处理用到了quartz定时任务,在此记录下quartz的配置吧,一个小demo仅供参考,也方便自己今后复习! 下面直接来步骤吧! 一.首先,要搭起能让quartz正常运行的环境,至少 ...

  5. Spring中实现定时调度

    1,   内容简介 所谓的定时调度,是指在无人值守的时候系统可以在某一时刻执行某些特定的功能采用的一种机制,对于传统的开发而言,定时调度的操作分为两种形式: 定时触发:到某一时间点上执行某些处理操作: ...

  6. 基于Azkaban的任务定时调度实践

    本文由云+社区发表 作者:maxluo 一.Azkaban介绍 Azkaban是LinkedIn开源的任务调度框架,类似于JavaEE中的JBPM和Activiti工作流框架. Azkaban功能和特 ...

  7. 定时调度系列之Quartz.Net详解

    一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提醒用户XXX "."每天的0点需要统计前一天的考勤记录"."每个月 ...

  8. Java学习笔记 -- Java定时调度工具Timer类

    1 关于 (时间宝贵的小姐姐请跳过) 本教程是基于Java定时任务调度工具详解之Timer篇的学习笔记. 什么是定时任务调度 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Ja ...

  9. Spring+Quartz集群环境下定时调度的解决方案

    集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...

  10. 定时调度篇之Quartz.Net详解(被替换)

    一. 背景 我们在日常开发中,可能你会遇到这样的需求:"每个月的3号给用户发信息,提醒用户XXX "."每天的0点需要统计前一天的考勤记录"."每个月 ...

随机推荐

  1. 一个简单高效低内存的.NET操作Excel开源框架 - MiniExcel

    前言 日常工作中经常与数据打交道的同学肯定会难以避免对Excel的一些数据操作如导入.导出等,但是当对一些大数据量操作Excel时经常会遇到一个常见的问题内存溢出.今天给大家推荐一个简单.高效.低内存 ...

  2. 如何使用SHC对Shell脚本进行封装和源码隐藏

    在许多情况下,我们需要保护我们的shell脚本源码不被别人轻易查看.这时,使用shc工具将shell脚本编译成二进制文件是一个有效的方法.本文将详细介绍如何在线和离线条件下安装shc,并将其用于编译你 ...

  3. 从零开始学习web前端技术路线图

    最近我侄子快实习了,学校跟培训机构合作,交两万多可以参与一个培训,培训四个月,可以包就业.侄子问我,是否要去培训,培训出来可以找到工作吗? 现在很多大学生,上学的时候谈恋爱,玩游戏,快要毕业就焦虑了. ...

  4. Redis7新特性简介及十大数据类型

    Redis是基于内存的K-V键值对内存数据库 浅谈Redis7新特性 主要是自身底层性能和资源利用率上的提高和优化. 多AOF文件支持 config命令增强 限制客户端内存使用 listpack紧凑列 ...

  5. 基于亚博k210+arduino 智能垃圾桶(23工训赛)

    #2023 10 15 派大星改 # object classifier boot.py # generated by maixhub.com from fpioa_manager import * ...

  6. 龙芯发布 .NET 8 SDK 8.0.100-rc2 LoongArch64

    随着.NET 8的发布的临近,国内的社区朋友们也很关心龙芯.NET 团队对于Loongarch .NET 8的发布时间,目前从龙芯.NET编译器团队的可靠信息,Loongarch .NET 8的发布会 ...

  7. QT实战 之翻金币游戏

    QT实战 之翻金币游戏 相较于原版的优化: 关卡数据不是用静态的config配置,而是动态生成,每次打开的关卡都生成不同的游戏数据,增加了可玩性: 关卡数据依据关卡等级的不同而生成不同难度的数据,随关 ...

  8. markdown文字与图片对齐方式

    markdown文字与图片对齐方式 一.图片文字左右对齐 //如图所示,左文字,右图片 <div align="center"> <table rules=&qu ...

  9. 如何收集pod重启前现场

    之前分享过几篇优化pod重启的文章,有朋友发私信问:看你的优化文章很过瘾,可否分享下如何收集pod重启前的现场. 案例分享-full gc导致k8s pod重启 记一次k8s pod频繁重启的优化之旅 ...

  10. JSR223取样器详解

    相比于BeanShell 取样器,JSR223取样器具有可大大提高性能的功能(编译)如果需要,一定要使用JSR223取样器编写脚本是更好的选择!!! 属性描述名称:显示的此取样器的描述性名称,可自定义 ...