Django高级扩展之celery使用

这篇具有很好参考价值的文章主要介绍了Django高级扩展之celery使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Celery是一个简单、灵活、可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需的工具。是一个专注于实时处理的任务队列,同时还支持任务调度。

目录

应用场景

问题

解决

celery架构图

安装

配置celery

Settings.py配置

创建celery

修改__init__

开启celery

异步执行

创建任务文件

视图

路由

演示

启动django

重启celery

浏览器访问

获取执行结果

AsyncResult属性和方法

演示

视图

路由

浏览器访问

Celery报错

kombu.async.timer

cannot import name 'current_app'

AttributeError

定时执行

增加配置

多个任务执行

创建执行方法

启动celery

绑定任务

实现绑定

实现错误重试

celery管理和监控

安装

运行命令

运行flower

浏览器访问

总结

参考文章


应用场景

问题

1.用户发起请求,需要等待响应返回;但是在视图中如果有一些耗时操作,可能导致用户会等待很长时间,这样用户体验非常不好。

2.网站隔一段时间要同步一次数据,但是http请求是需要触发的。

解决

使用celery来解决:耗时的操作方法在celery中异步执行;还可以使用celery定时执行。

 

celery架构图

celery由以下四部分构成:

任务(Task)、代理(Broker)、任务执行(Worker)、结果存储(Backend)。

Django高级扩展之celery使用

 

安装

命令如下:

pip install celery
pip install redis

# window下安装,linux下不需要
pip install eventlet

 

配置celery

Settings.py配置

Settings.py中在最下面配置

# celery配置
# Broker配置,使用Redis作为消息中间件
BROKER_URL = 'redis://127.0.0.1:6379/1'
# 若有密码这样配置
# BROKER_URL = 'redis://:pwd@127.0.0.1:6379/1'

# BACKEND配置,这里使用redis
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1'
# 若有密码这样配置
# CELERY_RESULT_BACKEND = 'redis://:pwd@127.0.0.1:6379/1'

# 结果序列化方案
CELERY_RESULT_SERIALIZER = 'json'

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

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

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

 

创建celery

在工程目录下的project目录下创建celery.py文件。

Django高级扩展之celery使用

内容如下:

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


# 设置系统环境变量,安装django,必须设置,否则在启动celery时会报错

# project 是当前工程目录名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')

celery_app = Celery('project')
celery_app.config_from_object('django.conf:settings')
celery_app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

修改__init__

在工程目录下project的__init__文件中添加

from .celery import celery_app

__all__ = ['celery_app']

开启celery

Window命令如下:

celery  -A project worker  -l debug -P eventlet

pip 安装eventlet,在启动celery的参数加上eventlet,

原理是windows不支持celery的进程执行。

Linux 命令如下:

celery  -A project worker  -l

成功截图如下:

Django高级扩展之celery使用

Redis数据库 

Django高级扩展之celery使用

 

异步执行

创建任务文件

在子应用目录下创建tasks.py来执行任务(写耗时异步执行)

Django高级扩展之celery使用

内容如下:

from celery import shared_task
import time



@shared_task
def add(x, y):
    print('添加一个事件')
    time.sleep(10)
    print(x, y)
    print('事件执行完成')

视图

应用视图views.py中增加引入和视图方法

from .tasks import *


def task_add(request):
    add.delay(100, 200)
    return HttpResponse(f'调用函数结果')

路由

urlpatterns = [
    # celery
    path(r'task_add', views.task_add, name='task_add'),
]

演示

启动django

python manage.py runserver

重启celery

celery  -A project worker  -l debug -P eventlet

浏览器访问

然后浏览器访问task路由。

Django高级扩展之celery使用

 通过worker的控制台,可以看到任务被worker处理。

Django高级扩展之celery使用

获取执行结果

可通过AsyncResult对象通过返回的事件id来获取事件信息。

AsyncResult属性和方法

state: 返回任务状态,等同status;

task_id: 返回任务id;

result: 返回任务结果,同get()方法;

ready(): 判断任务是否执行以及有结果,有结果为True,否则False;

info(): 获取任务信息,默认为结果;

wait(t): 等待t秒后获取结果,若任务执行完毕,则不等待直接获取结果,若任务在执行中,则wait期间一直阻塞,直到超时报错;

successful(): 判断任务是否成功,成功为True,否则为False;

演示

视图

from celery import result
from django.http import JsonResponse


def task_info(request):

    task_id = request.GET.get('task_id')

    res = result.AsyncResult(task_id)
    if res.ready():
        return JsonResponse({'status': res.state, 'result': res.get()})
    else:
        return JsonResponse({'status': res.state, 'result': ''})

路由

path(r'task_info/<str:id>', views.task_info, name='task_info'),

浏览器访问

地址栏传入新增事件时,返回的事件id

Django高级扩展之celery使用

 

Celery报错

kombu.async.timer

开启celery,提示错误Kombu.async.timer import Entry......

Django高级扩展之celery使用

解决方法:

卸载celery,重装固定版本

命令如下:

pip install celery==4.3

 

cannot import name 'current_app'

cannot import name 'current_app' from 'celery'

Django高级扩展之celery使用

解决方法:

打开D:\python3.7\lib\site-packages\celery\local.py"

原方法

def getappattr(path):
    """Get attribute from current_app recursively.

    Example: ``getappattr('amqp.get_task_consumer')``.

    """
    from celery import current_app
    return current_app._rgetattr(path)

修改为:

def getappattr(path):

    """Get attribute from current_app recursively.

    Example: ``getappattr('amqp.get_task_consumer')``.


    """
    # from celery import current_app
    from celery._state import current_app
    return current_app._rgetattr(path)

AttributeError

AttributeError: 'EntryPoints' object has no attribute 'get'

Django高级扩展之celery使用

解决方法:

安装固定版本的importlib-metadata

命令如下:

pip install importlib-metadata==4.13.0

 

定时执行

增加配置

工程目录下/settings.py

CELERYBEAT_SCHEDULE = {
    'every_5_seconds': {
        # 任务路径 应用目录/任务文件/方法
        'task': 'myapp.tasks.schedule_execute',
        # 每5秒执行一次
        'schedule': 5,
        # 设置参数
        'args': (14, 6, 5)
    }
}

多个任务执行

可在原来基础上继续增加

CELERYBEAT_SCHEDULE = {
    'every_5_seconds': {
        # 任务路径 应用目录/任务文件/方法
        'task': 'myapp.tasks.schedule_execute',
        # 每5秒执行一次
        'schedule': 5,
        # 设置参数
        'args': (14, 6, 5)
    },
    'every_10_seconds': {
        # 任务路径 应用目录/任务文件/方法
        'task': 'myapp.tasks.schedule_execute',
        # 每10秒执行一次
        'schedule': 10,
        # 设置参数
        'args': (18, 10, 10)
    },
}

创建执行方法

在task.py中设置执行方法并记录日志

from celery import shared_task
import logging

logger = logging.getLogger(__name__)


@shared_task
def schedule_execute(x, y, s):
    logger.info('_____' * 20)
    logger.info('每%d秒执行一次' % s)
    logger.info('%d + %d = %d' % (x, y, (x+y)))
    logger.info('执行结束')
    logger.info('_____' * 20)

启动celery

(两个cmd)分别启动worker和beat

celery -A project worker -l debug -P eventlet
celery beat -A project -l debug

可通过控制台查看执行结果。

绑定任务

Celery可通过task绑定到实例获取到task的上下文,这样我们可以在task运行时候获取到task的状态,记录相关日志等

实现绑定

修改应用任务文件内容:在装饰器中加入参数 bind=True,在add函数中的第一个参数设置为self。

内容如下:

@shared_task(bind=True)
def add(self, x, y):

    print('添加一个事件')
    time.sleep(2)
    print(x, y)
    logger.info(self.name)
    logger.info(dir(self))
    print('事件执行完成')

实现错误重试

self对象是myapp.tasks.add实例,可用于实现重试。

@shared_task(bind=True)
def add(self, x, y):

    try:
        print('添加一个事件')
        time.sleep(2)
        print(x, y)
        logger.info(self.name)
        # 没有state属性 只是为了验证重试
        logger.info(self.state)
        logger.info(dir(self))
        print('事件执行完成')

    except Exception as e:

        # 出错每5秒尝试一次,尝试3次
        self.retry(exc=e, countdown=5, max_retries=3)

 

celery管理和监控

celery通过flower组件实现管理和监控功能。

Flower官网

Getting started — Flower 2.0.0 documentation

安装

pip install flower

运行命令

celery -A project flower

Or

celery -A project flower --port=5001

参数说明

-A 项目名称

--port 端口号,默认5555

运行flower

运行命令,显示如下:

Django高级扩展之celery使用

浏览器访问

http://127.0.0.1:port

Django高级扩展之celery使用

 

总结

本文主要介绍了celery的应用场景;

如何安装及安装哪些类库;

异步和定时执行实现以及任务可视化管理。

参考文章

https://www.cnblogs.com/chunyouqudongwuyuan/p/16892475.html

Django 中celery的使用_django celery_宠乖仪的博客-CSDN博客

在django中使用celery_哔哩哔哩_bilibili

一文读懂 Python 分布式任务队列 celery文章来源地址https://www.toymoban.com/news/detail-502629.html

到了这里,关于Django高级扩展之celery使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • redis(其它操作、管道)、django中使用redis(通用方案、 第三方模块)、django缓存、celery介绍(celery的快速使用)

    1 redis其它操作 2 redis管道 3 django中使用redis 3.1 通用方案 3.2 第三方模块 4 django缓存 5 celery介绍 5.1 celery的快速使用

    2024年02月07日
    浏览(50)
  • Django(21):使用Celery任务框架

    Django Web项目中我们经常需要执行耗时的任务比如发送邮件、调用第三方接口、批量处理文件等等,将这些任务异步化放在后台运行可以有效缩短请求响应时间。另外服务器上经常会有定时任务的需求,比如清除缓存、备份数据库等工作。Celery是一个高效的异步任务队列/基于

    2024年02月07日
    浏览(36)
  • django中使用celery和接口缓存

    celery中要使用djagno的东西,才要加这句话         import os                          os.environ.setdefault(\\\"DJANGO_SETTINGS_MODULE\\\", \\\"luffy_api.settings.dev\\\") 加载django的配置文件,,将app加入到环境变量中 当一个接口是去数据库取东西,返回给前端,比如图片,等,每个人访问都要去数

    2024年02月12日
    浏览(80)
  • Django 如何使用 Celery 完成异步任务或定时任务

    以前版本的 Celery 需要一个单独的库(django-celery)才能与 Django 一起工作, 但从 Celery 3.1 开始,情况便不再如此,我们可以直接通过 Celery 库来完成在 Django 中的任务。 以 Docker 安装为例,安装一个密码为 mypassword 的 Redis 服务端 在 Django 项目中创建一个 celery.py 文件,并配置

    2023年04月25日
    浏览(50)
  • Django+Celery学习笔记

    Django+Celery学习笔记 DJANGO中使用CELERY实现定时任务(用DJCELERY) https://www.cnblogs.com/wumingxiaoyao/p/8521567.html Django中celery机制的使用总结 https://blog.csdn.net/Enjolras_fuu/article/details/108513357 代码 https://github.com/furuiyang0715/celery_learn 参考 https://www.celerycn.io/yong-hu-zhi-nan/canvas-she-ji-gong-zuo-liu-che

    2024年02月12日
    浏览(39)
  • django celery 记录

    django celery 记录 dvadmin-celery Django+Django-Celery+Celery的整合实战 https://cloud.tencent.com/developer/article/1445252 https://blog.csdn.net/wowocpp/article/details/131475484 https://docs.celeryq.dev/en/latest/django/first-steps-with-django.html https://docs.celeryq.dev/en/latest/django/index.html http://docs.celeryproject.org/en/latest/ https://

    2024年02月12日
    浏览(35)
  • Django+celery开启时报错

    django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias \\\'default\\\' was created in thread id 19767205568 00 and this is thread id 1976775359680. 问题: 执行celery worker -A s1 -l info -P eventlet能正常,放立即执行的任务(delay)没有问题,不过放apply_async的任务

    2024年02月11日
    浏览(43)
  • django celery period 周期 例子

    django celery period 周期 例子 Django 借助 Celery 实现计划任务排期及调度系统(django-celery-beat) good https://www.jianshu.com/p/f22346379dbe https://django-celery-results.readthedocs.io/en/latest/ https://django-celery-beat.readthedocs.io/en/latest/ 五、运行测试 为了使系统正常运行,需要同时开启三个服务: web 服

    2024年02月12日
    浏览(42)
  • 利用Django和Celery管理定时任务

    同步发表于个人站点: http://panzhixiang.cn/article/2023/3/16/68.html 我们以前一直使用k8s的cronjob来管理定时任务的。把定时任务相关的代码单独封装成一个pod,然后以cronjob的方法来触发。 虽然这个方法操作很简单,没有什么第三方资源的依赖(比如Redis),但是也有一个明显的缺点

    2024年02月07日
    浏览(81)
  • Django+Celery框架自动化定时任务开发

    本章介绍使用DjCelery即Django+Celery框架开发定时任务功能,在Autotestplat平台上实现单一接口自动化测试脚本、业务场景接口自动化测试脚本、App自动化测试脚本、Web自动化测试脚本等任务的定时执行、调度、管理等,从而取代Jenkins上的定时执行脚本和发送邮件等功能。** 自动化

    2024年04月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包