Django中使用celery实现定时任务和异步任务

第一步安装

pip install celery

选择消息代理

​ 使用于生产环境的消息代理有 RabbitMQ 和 Redis, 官方推荐 RabbitMQ

Celery 序列化
​ 在客户端和消费者之间传输数据需要 序列化和反序列化. Celery 支出的序列化方案如下所示:

五. 安装,配置与简单示例
Celery 配置参数汇总

代码示例 :

注意上半部分是异步任务的配置 如果要配置定时任务才加下面注释掉的部分

定时任务不一定要写在 Django 的视图方法中,您可以使用 Celery 或其他任务调度工具来定时执行任务,而不必依赖于视图方法。

# Broker配置,使用Redis作为消息中间件
BROKER_URL = 'redis://:6379/0'

# BACKEND配置,这里使用redis 指定 Redis 连接地址,用于存储任务结果
CELERY_RESULT_BACKEND = 'redis://6379/0'

# celery内容等消息的格式设置,默认json
CELERY_ACCEPT_CONTENT = ['application/json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

# 任务结果过期时间,秒
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True


# 时区配置
CELERY_TIMEZONE='Asia/Shanghai'

# 指定导入的任务模块,可以指定多个
CELERY_IMPORTS = (
   # 'bbs.tasks',
    'echartsapp.tasks',
)
CELERY_TASK_TIME_LIMIT = 5



# 定义定时任务的配置
# CELERY_BEAT_SCHEDULE = {
#     'sync-redis-to-mysql': {
#         # 'task': 'bbs.tasks.sync_redis_to_mysql',  # 替换为您的任务函数路径
#         # 'schedule': crontab(minute=0, hour=0),  # 在每天的午夜触发任务
#         'task': 'bbs.tasks.scheduled_task',
#         # 每10s执行一次
#         'schedule': timedelta(seconds=10),
#     },
# }

配置celery.py 在根项目路径下

import os
import django
from celery import Celery
from django.conf import settings

# 设置系统环境变量,安装django,必须设置,否则在启动celery时会报错
# djangotest 是当前项目名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoTest.settings')
#实例化一个celery类
django.setup()

celery_app = Celery('djangoTest')
#指定配置文件的位置
celery_app.config_from_object('django.conf:settings', namespace='CELERY')
#自动从settings的配置INSTALLED_APPS中的应用目录下加载 tasks.py
celery_app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

配置init.py 在根项目路径下  一般也可不配这个

from __future__ import absolute_import, unicode_literals
from .celery import celery_app

__all__ = ['celery_app']

调用任务的方法 :

1. delay
task.delay(args1, args2, kwargs=value_1, kwargs2=value_2)

2. apply_async
delay 实际上是 apply_async 的别名, 还可以使用如下方法调用, 但是 apply_async 支持更多的参数:

task.apply_async(args=[arg1, arg2], kwargs={key:value, key:value})

支持的参数 :

countdown : 等待一段时间再执行.

add.apply_async((2,3), countdown=5)

eta : 定义任务的开始时间.

add.apply_async((2,3), eta=now+tiedelta(second=10))

expires : 设置超时时间.

add.apply_async((2,3), expires=60)

retry : 定时如果任务失败后, 是否重试.

add.apply_async((2,3), retry=False)

retry_policy : 重试策略.

​ max_retries : 最大重试次数, 默认为 3 次.

​ interval_start : 重试等待的时间间隔秒数, 默认为 0 , 表示直接重试不等待.

​ interval_step : 每次重试让重试间隔增加的秒数, 可以是数字或浮点数, 默认为 0.2

​ interval_max : 重试间隔最大的秒数, 即 通过 interval_step 增大到多少秒之后, 就不在增加了, 可以是数字或者浮点数, 默认为 0.2 .

自定义发布者,交换机,路由键, 队列, 优先级,序列方案和压缩方法:

task.apply_async((2,2), compression=‘zlib’, serialize=‘json’, queue=‘priority.high’, routing_key=‘web.add’, priority=0, exchange=‘web_exchange’)

编写任务

一般是在 app 下新建一个 task 文件,里面写周期性的任务,使用 @app.task 装饰器定义。
task.py: 在你的app下

@shared_task
def sync_redis_to_mysql(key,pk):
    # 获取 Redis 中的计数值
    # celery - A djangoTest beat

    redis_count = cache.get(key) or 0
    dbv = key.split('-')[0]
    # 获取数据库中的值
    # view_count = serializer.data.get('view_count')
    db_count = TTopic.objects.values_list(dbv, flat=True).get(article_id=pk)

    # 将 Redis 计数值加到数据库中
    TTopic.objects.filter(pk).update(dbv=db_count + redis_count)

    # 清空 Redis 中的计数值
    cache.delete(key)

异步调用任务
Celery调用异步任务有三个方法:

app.send_task 不是很常用

# tasks.py
from celery import Celery
app = Celery()
def add(x,y):
    return x+y

app.send_task('tasks.add',args=[10,20]) 
 # 参数基本和apply_async函数一样# 但是send_task在发送的时候是不会检查tasks.add函数是否存在的,即使为空也会发送成功,所以celery执行是可能找不到该函数报错;


Task.delay

def inset(request):
    test.delay(args=[3,5])
    return HttpResponse('ok')
 Task.delay(参数1, 参数1, 键值, kwargs2=value_2)


Task.apply_async 与delay类似,但支持更多参数

 def inset(request):
    result = test.apply_async(args=[4,5])
    return HttpResponse('ok')
 task.apply_async(args=[arg1, arg2], kwargs={key:value, key:value})


测试:当你通过浏览器访问链接时,你根本感受不到2s的延迟,页面可以秒开,同时你会发现终端的输出显示任务执行成功。

使用 apply_async 方法调用 test 任务还能打印任务 id 和任务 status

def inset(request):
    result = test.apply_async(args=[3,5])
    print(result.id)
    print(result.status)
    return HttpResponse('ok')

执行任务

在使用 Celery 执行异步任务时,通常需要先运行 Celery 服务(工作进程)然后再运行您的项目。这是因为 Celery 工作进程会独立运行并监听队列,以便随时处理异步任务。

下面是一般的步骤:编写任务,

  1. 先运行 Celery 服务:

    celery -A your_project_name worker --loglevel=info

    这将启动 Celery 工作进程,它会一直运行,等待执行异步任务。

  2. 然后运行您的项目:

    python manage.py runserver

    或者根据您的项目配置方式启动 Django 项目。您的项目运行后,可以通过视图方法或其他方式触发异步任务的执行。

  3. 如果您有定时任务,还可以启动 Celery Beat 服务来调度这些任务:

    celery -A your_project_name beat --loglevel=info

    celery -A your_project_name beat --loglevel=info

    这将启动 Celery Beat 服务,它将按照预定的时间表执行定时任务。

请注意,Celery 和您的项目是独立运行的,它们之间通过消息队列进行通信。当您的项目触发异步任务时,它会将任务放入消息队列,然后 Celery 工作进程会从队列中获取任务并执行。这种方式可以确保异步任务不会阻塞或影响您的主项目。

更多可查看中文文档
前言 - Celery 中文手册

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Celery是一个Python分布式任务队列,它可以帮助我们异步执行任务,而且还可以定时执行任务。下面是使用DjangoCelery框架来实现定时任务执行的步骤: 1. 安装Celery。可以使用pip工具来安装Celery。 ```bash pip install celery ``` 2. 配置Django项目。在Django项目的settings.py文件加入以下配置: ```python INSTALLED_APPS = [ # ... 'django_celery_results', 'django_celery_beat', # ... ] CELERY_BROKER_URL = 'redis://localhost:6379' CELERY_RESULT_BACKEND = 'django-db' CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_RESULT_SERIALIZER = 'json' CELERY_TASK_SERIALIZER = 'json' ``` 其CELERY_BROKER_URL是指定Celery使用Redis作为消息代理,CELERY_RESULT_BACKEND是指定Celery的结果存储方式为Django数据库,CELERY_ACCEPT_CONTENT、CELERY_RESULT_SERIALIZER和CELERY_TASK_SERIALIZER则是指定消息的序列化方式。 3. 创建定时任务。在Django项目的tasks.py文件定义需要定时执行任务。例如: ```python from celery import shared_task @shared_task def hello(): print('Hello, World!') ``` 4. 配置定时任务。在Django项目的settings.py文件加入以下配置: ```python CELERY_BEAT_SCHEDULE = { 'hello_task': { 'task': 'tasks.hello', 'schedule': 10.0, }, } ``` 其,'hello_task'是任务的名称,'task'指定了任务的函数名,'schedule'则指定了任务执行间隔时间。 5. 启动Celery。在Django项目的根目录下执行以下命令启动Celery: ```bash celery -A your_project_name worker -l info -B ``` 其,-A参数指定了Celery要加载的Django项目的名称,-B参数表示启用定时任务。 6. 测试定时任务是否生效。等待10秒钟后,可以在控制台看到输出了'Hello, World!',表示定时任务已经成功执行。 以上就是使用DjangoCelery框架来实现定时任务执行的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值