Celery动态添加定时任务
背景
业务需求:用户可创建多个多人任务,需要在任务截止时间前一天提醒所有参与者
技术选型:
Celery:分布式任务队列。实现异步与定时
django-celery-beat:实现动态添加定时任务,即在创建多人任务时添加定时。django-celery-beat插件本质上是对数据库表变化检查,一旦有数据库表改变,调度器重新读取任务进行调度
安装与配置
安装
pip install celery
pip install django-celery-beat
配置
INSTALLED_APPS = (
...,
'django_celery_beat',
)
# settings.py
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
# =================Celery 配置=================
# 使用redis作为broker
REDIS_HOST = 'redis://127.0.0.1:6379/0'
# 关闭 UTC
CELERY_ENABLE_UTC = False
# 设置 django-celery-beat 真正使用的时区
CELERY_TIMEZONE = TIME_ZONE
# 使用 timezone naive 模式,不存储时区信息,只存储经过时区转换后的时间
DJANGO_CELERY_BEAT_TZ_AWARE = False
# 配置 celery 定时任务使用的调度器,使用django_celery_beat插件用来动态配置任务
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
创建django-celery-beat所需要的数据表
python manage.py migrate
创建celery实例,并定义任务
# 由于django_celery_beat用到了Django的ORM,因此首先需要setup django,否则会报错
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "qaboard.settings")
django.setup()
from celery import Celery
from project import settings
from utils.send_msg import send_msg
# 使用redis作为消息队列,backend也默认为broker使用的队列服务
app = Celery('test', broker=settings.REDIS_HOST)
# 载入django配置文件中以 CELERY 开头的配置
app.config_from_object('project.settings', namespace='CELERY')
@app.task
def test_task():
send_msg("test celery")
启动celery worker和celery beat
celery -A project_celery worker --pool=solo -l info -f logs/celery.log
'-A' 是一个全局配置,定义了APP的位置
'--pool' 是POOL的配置,默认是prefork(并发),选择solo之后,发送的任务不会被并发执行,在worker执行任务过程中,再次发送给worker的任务会排队,执行完一个再执行另一个。不需要并发时可以选择此模式以节约服务器资源
'-l' 定义了log级别
'-f' 定义日志文件路径
celery -A project_celery beat -l info -f logs/beat.log --pidfile=logs/celerybeat.pid
'--pidfile' 用于定位pidfile,pidfile是一个存储了beat进程的进程id的文件,如果此文件存在且此文件中的进程正在运行中,则不会启动新的beat进程
由于配置中已经声明了调度器,因此这里不需要重新声明,否则需要使用
--scheduler django_celery_beat.schedulers:DatabaseScheduler
声明使用DatabaseScheduler
在linux上可以用-B参数同步启动celery beat
celery -A qaboard_celery worker --pool=solo -l info -f logs/celery.log -B
beat的log会输出到celery.log中
动态添加定时任务
PeriodicTask
此模型定义要运行的单个周期性任务。
- 必须为任务指定一种Schedule,即clocked, interval, crontab, solar四个字段必须填写一个,且只能填写一个
- name字段给任务命名,它是unique的
- task字段指定运行的Celery任务,如“proj.tasks.test_task”
- one_off:默认值为False,如果one_off=True,任务被运行一次后enabled字段将被置为False,即任务只会运行一次
- args:传递给任务的参数,是一个json字符串,如 ["arg1", "arg2"]
- expires:过期时间,过期的任务将不再会被驱动触发
使用ClockedSchedule
会在特定的时间触发任务
def test_clock():
clock = ClockedSchedule.objects.create(clocked_time=datetime.now() + timedelta(seconds=10))
PeriodicTask.objects.create(
name="%s" % str(datetime.now()),
task="project_celery.celery_app.test_task",
clocked=clock,
# 如果使用ClockedSchedule,则one_off必须为True
one_off=True
)
不知道为什么我的任务就是无法通过clock触发,beat.log中有DatabaseScheduler: Schedule changed.的记录,但是到了clock指定的时间任务不会被触发,其他的调度器都是可以正常运行的,如果有知道解决方法的同学可以评论告诉我,感谢
使用IntervalSchedule
以特定间隔运行的Schedule
用IntervalSchedule能够实现与ClockedSchedule同样的功能:计算目标时间与当前时间的时间差,令此时间差作为IntervalSchedule的周期,并且将任务的one_off参数置为True
def time_diff(target_time):
diff = target_time - datetime.now()
return int(diff.total_seconds())
def test_interval():
seconds = time_diff(datetime.strptime("2020-3-19 15:39:00", "%Y-%m-%d %H:%M:%S"))
schedule = IntervalSchedule.objects.create(every=seconds, period=IntervalSchedule.SECONDS)
PeriodicTask.objects.create(
name="%s" % str(datetime.now()),
task="project_celery.celery_app.test_task",
interval=schedule,
one_off=True
)
使用CrontabSchedule
使用CrontabSchedule一定要注意将时区设置为当前地区时区
model参数与crontab表达式的对应关系:
minite, hour, day_of_week, day_of_month, month_of_year
全部默认为"*"
def test_crontab():
# 表示 * * * * * ,即每隔一分钟触发一次
schedule = CrontabSchedule.objects.create(timezone='Asia/Shanghai')
PeriodicTask.objects.create(
name="%s" % str(datetime.now()),
task="project_celery.celery_app.test_task",
crontab=schedule,
one_off=True
)
Celery动态添加定时任务的更多相关文章
- Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务
Celery 分布式任务队列快速入门 以及在Django中动态添加定时任务 转自 金角大王 http://www.cnblogs.com/alex3714/articles/6351797.html ...
- Quartz动态添加定时任务执行sql(服务启动添加+手动添加)
系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...
- elastic-job动态添加定时任务
在elastic-job的使用过程中,我们会遇到动态添加定时任务的时候,但是官网上面并没有对这块内容进行说明.按照我的理解以及官网上面elastic-job的框架图,ej的定时任务其实是存储在zook ...
- 动态添加定时任务-quartz定时器
Quartz动态添加.修改和删除定时任务 在项目中有一个需求,需要灵活配置调度任务时间,刚开始用的Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务 ...
- Spring动态添加定时任务
Spring动态添加定时任务 一.背景 二.需求和实现思路 1.能够动态的添加一个定时任务. 2.能够取消定时任务的执行. 3.动态的修改任务执行的时间. 4.获取定时任务执行的异常 三.代码实现 四 ...
- celery 动态配置定时任务
How to dynamically add or remove tasks to celerybeat? · Issue #3493 · celery/celery https://github.c ...
- Spring+Quartz实现动态添加定时任务
发布时间:2018-12-03 技术:spring4.0.2+quartz2.2.1 概述 在最近工作中,由于涉及到定时任务特别多,而这些工作又是由下属去完成的,在生成环境中经常会出现业务逻辑 ...
- celery 动态定时任务探索
环境: celery 4.3 flask python 3.7 linux 需求: 动态添加定时任务,且方便维护. 解决思路: 参考django-celery 或是celery源码,将定时任务配置放置 ...
- Quartz动态添加,修改,删除任务(暂停,任务状态,恢复,最近触发时间)
首页 博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITeye GitChat 写博客 小程序 消息 登录注册 关闭 quartz_Cron表达式一分钟教程 09-05 ...
随机推荐
- 读《Java并发编程的艺术》学习笔记(一)
接下来一个系列,是关于<Java并发编程的艺术>这本书的读书笔记以及相关知识点,主要是为了方便日后多次复习和防止忘记.废话不多说,直接步入主题: 第1章 并发编程的挑战 并发编程的目的是 ...
- 解决Hexo博客模板hexo-theme-next的翻页按钮不正常显示问题
用Hexo搭了个Gitpage的博客,兴冲冲的发了11篇博文后发现翻页按钮不正常显示,显示为<i class="fa fa-angle-right"></i> ...
- 304 Not Modified
304 Not Modified,不是服务器发出的错误,是服务器所承载的业务系统在开发时为了节省带宽和提升浏览器的体验,对GET/js,css,image等执行了缓存机制.客户端第一次对服务器发出GE ...
- NTP网络时钟服务器品牌
NTP网络时钟服务器品牌 在科技的不断进步和发展下,时钟的种类和功能也在发生着变化,以满足人们的各种需求,时钟从原始的机械时钟发展成具有多钟功能的时钟.而时钟服务器主要是给时钟提供时间信息的,时钟服务 ...
- java编写非对称加密,解密,公钥加密,私钥解密,RSA,rsa
非对称加密已经被评为加密标准,主要包含(公钥加密私钥解密,或者私钥加密公钥解密)本文主要讲解的是如何用java生成 公钥和私钥并且 进行字符串加密 和字符串解密 //如需要代码copy如下 im ...
- 简述N种排序算法
排序算法概述 排序算法是程序员日常很常见的算法,基本上每天都会使用排序,在这里将进行一下总结. 排序算法大致可分为比较类排序和非比较类排序二种,其核心区别可以简单的理解为非比较类排序是对比较类排序之前 ...
- 初识JVM:(二)Java的垃圾回收机制详解
声明:本文主要参考https://www.cnblogs.com/codeobj/p/12021041.html 仅供个人学习.研究之用,请勿用于商业用途,如涉及侵权,请及时反馈,立刻删除. 一.Ja ...
- RPA如何跑赢传统自动化和人工?
过去的4年时间里,RPA(机器人流程自动化)一词,在Gartner的搜索引擎中一直排名前五.去年Gartner发表的调查数据中显示,RPA行业在2018年保持了60%以上的增长速度,从而成为全球增长最 ...
- 使用Servlet和JSp在浏览器上实现对数据库表的增删改查(新手)
第一步:用户输入网址进入一个登陆界面. 里面要有账号密码输入. 登陆界面链接到登陆的Servlet类中. Servlet类 --> 1.接收参数(账户密码) 2.调用DAO层的 SQL语句 验 ...
- Netty Hello World 入门源码分析
第一节简单提了什么是网络编程,Netty 做了什么,Netty 都有哪些功能组件.这一节就具体进入 Netty 的世界,我们从用 Netty 的功能实现基本的网络通信开始分析 各个组件的使用. 1. ...