Python & Celery 学习笔记_任务排程

本篇内容主要在讨论,该如何让 celery 在指定时间执行任务
过程中如果有错误,欢迎留言讨论喔 ~

一、建立 task

from celery import Celeryfrom setting import broker_url, backend_urlfrom datetime import datetimeapp = Celery("celery_start", broker=broker_url, backend=backend_url)@app.taskdef get_time(name: str):    now = datetime.now()    return f"Hello {name} 现在时间为 {now.strftime('%Y-%m-%d, %H:%M:%S')}"

二、countdown 参数

countdown 参数单位为秒,使用这个参数可以让 celery worker 在收到任务后
过了指定单位的秒数再执行

get_time.apply_async(("nick",), countdown=20)

下图中我们可以看到 celery 在收到任务后,过了大约 20 秒才执行任务
http://img2.58codes.com/2024/20144024zs6j0cxJBm.jpg

三、eta 参数

eta 参数接收的资料型态须为 datetime 物件,但要特别注意,celery 内部所接收的时间
是 UTC 标準时间,虽然说 celery 本身有提供一些 config 可以让使用者作设定,但是对
于时区的部分似乎是没有效果,因此如果要利用 eta 的话我们必须使用 pytz 这个套件对
时间做转换,下方为 pytz 的範例

from celery_schedule import get_timefrom datetime import datetime, timedeltaimport pytz# 先设定时区local_timezone = pytz.timezone("Asia/Taipei")# 产生一笔时间物件,并计算想要甚么时候执行任务# 也可以直接利用 datetime 直接指定一个日期now = datetime.now()exec_time = now + timedelta(seconds=10)# 利用 pytz 进行转换exec_time = local_timezone.localize(exec_time)# 送出任务get_time.apply_async(("nick",), eta=exec_time)

如下图所示,可以看到大约在 10 秒钟后任务就会被 celry worker 执行
http://img2.58codes.com/2024/20144024TMyHt619xX.jpg

四、expries 参数

expries 参数可以理解程,任务的到期时间,也就是这个任务最晚甚么时候要被执行,
前面有提到,celery 可以自动将任务进行排队,由于 worker 的 process 的数量有限
如果一次送太多任务,任务就必须进行排队,因此可以透过设定这个参数来告诉 celery
,该任务最晚必须于甚么时候执行

附注: 若 celery 收到 expries 已经过期的任务时,则 celery 会将任务状态标记为 revoke,代表不会去执行这个任务,任务状态相关的部分会于下一篇文章进行解说

附注: expries 可以接收的资料型态为 int (用于指定秒数) 以及 datetime (用于指定日期)

from celery_schedule import get_timefrom datetime import datetime, timedeltaimport pytz# 先设定时区local_timezone = pytz.timezone("Asia/Taipei")# 产生一笔时间物件,并计算想要甚么时候执行任务# 也可以直接利用 datetime 直接指定一个日期now = datetime.now()exec_time = now + timedelta(seconds=10)# 利用 pytz 进行转换exec_time = local_timezone.localize(exec_time)# 送出任务get_time.apply_async(("nick",), expries=exec_time)

如下图所示,可以看到 celery 在收到任务后马上执行,因为版主只有送了一个任务进入列队
http://img2.58codes.com/2024/201440248224kJqLfL.jpg

五、redis 重複派送任务问题

redis 对于长时间 eta 的处理不太优,常常会产生非预期的问题,例如重複派送任务等,可以看看这篇文章
若遇上此问题,可以考虑将 broker 换成 rabbitmq 或是利用 celery beat 重複检查看看是否有任务到期
若到期再用 delay 送进任务列队即可


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章