Django3.2 + Celery5.2实现异步任务


一、相关库版本信息

python==3.8.13
django==3.2.4 
redis==4.1.3 
celery==5.2
django-celery-beat==2.2.1

二、Task任务的分类

在程序中,任务大致可以分为同步任务和异步任务两种类型:
同步任务

指的是任务在主线程上需要排队执行的,只有前一个任务执行完毕,才能执行后一个任务。简单点就是说必须 等前一件事做完才能做下一件事。

异步任务

异步任务与同步则是相对的。当我们执行某个任务后,我们并不需要立即得到结果,我们可以正常地做其他操作,或者多次执行任务,这些任务不会等待前一个执行完再去执行,而且可以同时执行的,只需要执行完成后通知或者回调来告诉我们就可以了。

现在我们就是希望在Django框架中通过使用Celery实现异步任务的功能。

三、Celery简介

Celery是一个基于分布式消息传输的异步任务队列,它专注于实时处理,同时也支持任务调度。
Celery的组件介绍:

Beat:定时地将任务发往消息队列;
Worke:实时监视消息队列获取队列中的任务执行(可以一个或多个);
Broker:消息代理,又称消息中间件。就是生产者和消费者存放/拿取产品的地方(消费队列)。Celery目前支持RabbitMQ、Redis、MongoDB、Beanstalk、SQLAlchemy、Zookeeper等作为消息代理,官方推荐 RabbitMQ。
Result Backend:任务处理完后保存状态信息和结果,以供查询。

四、实现异步任务

项目目录
在这里插入图片描述
使用流程:

  1. 新建一个celery.py文件,此文件跟settings文件同级
    在这里插入图片描述
    代码:

    import os
    from celery import Celery
    from celery.utils.log import get_task_logger
    from celery.schedules import crontab
    
    # Set the default Django settings module for the 'celery' program.
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'K_AUTOTESTING.settings')
    
    app = Celery('K_AUTOTESTING')
    
    # Using a string here means the worker doesn't have to serialize
    # the configuration object to child processes.
    # - namespace='CELERY' means all celery-related configuration keys
    #   should have a `CELERY_` prefix.
    app.config_from_object('django.conf:settings', namespace='CELERY')
    
    # Load task modules from all registered Django apps.
    app.autodiscover_tasks()
    
    # 定时任务调度
    app.conf.beat_schedule = {
        "every-midnight-check-account-lock": { 
            'task': 'get_has_account_lock',
            "schedule": crontab(minute='*/2'),
            'args': ()
        }
    }
    
    @app.task(bind=True)
    def debug_task(self):
    	    print(f'Request: {self.request!r}')
    

    说明:根据实际情况修改项目名称“K_AUTOTESTING”

  2. setting文件配置celery相关信息

    CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://:@127.0.0.1:6379/0')
    # 存储结果后端
    CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'redis://127.0.0.1:6379/7')
    
    # 时区
    CELERY_TIMEZONE = 'Asia/Shanghai'
    CELERY_TASK_SERIALIZER = 'json'
    CELERY_TASK_TRACK_STARTED = True
    CELERY_TASK_TIME_LIMIT = 30 * 60
    
    # redis  相关配置信息
    REDIS_HOST = "127.0.0.1"
    REDIS_PORT = 6379  # 端口
    REDIS_PASSWORD = ""
    REDIS_SSL_STATUS = False  # 是否需要SSL
    REDIS_BASE_URL = "redis://127.0.0.1:6379/"  # 基础连接-用于连接池
    

    说明:此处使用redis作为消息队列

  3. 在子应用下如果需要异步任务,创建task.py文件

    importlogging
    import time
    from celery import shared_task
    from k_user import models
    
    # 如果logging.getLogger()加上子应用,日志会生成2行一模一样的
    logger = logging.getLogger()
    
    
    #测试celery异步
    @shared_task
    def test_celery(str):
        logger.info('当前已经进入到celery中')
        time.sleep(5)
        logger.info('传递过来的值为:%s'%str)
        logger.info('从celery中出来了')
    
    # 定时任务
    @shared_task(name="get_has_account_lock")
    def get_has_account_lock():
        # 将所有由于输入密码或验证码次数过多锁定的账户解锁
        logger.info("get_has_account_lock starting...")
        info = models.UserInfo.objects.all().values()
        print('信息:',info)
        logger.info("get_has_account_lock end...")
    
  4. 在view.py中写视图接口

    def celery_test(self, request):
        test_celery.apply_async(args=['hello,celery'])
        return Response({
            "code": "0001",
            "success": True,
            "msg": "定时任务执行成功"
        })
    
  5. 在子应用的urls.py中写接口绑定视图

    urlpatterns = [
        path('login/', LoginView.as_view()),    # 登录
        path('register/', RegisterView.as_view()),    # 注册
        path('user_list/', UserList.as_view({
            "get": "get_user_list"
        })),
        path('celery_test/', UserList.as_view({
            "get": "celery_test"
        }))
    ]
    
  6. 在managy.py同级开启终端
    启动命令:

    # 如果在linux上启动
    celery -A K_AUTOTESTING worker -l INFO &
    celery -A K_AUTOTESTING beat -l INFO &
    
    # 如果在windows上启动
    celery -A K_AUTOTESTING worker -l INFO -P eventlet
    celery -A K_AUTOTESTING beat -l INFO
    

    1、celery高版本不兼容windows,因此需要安装eventlet来兼容windows ,安装命令:pip install eventlet
    2、windows在启动celery worker时执行命令式 celery -A K_AUTOTESTING worker -l info -P eventlet

  7. 请求接口执行任务
    在这里插入图片描述
    执行日志,任务成功执行!
    在这里插入图片描述


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力向上搬砖侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值