老卫带你学---Celery+Redis

引言:

  当需要用python创建和完成定时任务时,第一个会想到的就是使用crontab库,

  但是crontab不支持Windows系统,于是我们可以使用一个支持Windows且功能强大的库:Celery。

Celery-分布式任务队列:

  Celery是一个简单,灵活,可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需的工具。

  它是一个任务队列,专注于实时处理,同时还支持任务调度。

  Celery是开源的,并根据BSD许可授权。

  Celery由Python语言实现。

Celery安装:

  celery的版本非常令人头疼,它的版本无法做到完全上下兼容,且有些版本会与一些库冲突,所以对于celery版本的选择非常重要:

    1、celery 4.0.0~4.2.0(latest) 目前最新的celery版本是官方的4.2.0 链接:http://docs.celeryproject.org/en/latest/

     (1) celery 4.0.0及以上版本目前不兼容python3.7 由于在python3.7中 async变成了关键字 在运行celery worker的时候会报错,

         

         from . import async,base 此处出错。

     (2) django-celery是一个便于在django工程中管理celery的库,但是django-celery不支持celery 4.0.0以上版本,如若要在django工程中

      使用celery,请降低版本,比如celery 3.1.26

    2、celery 3~4的版本之间 相对稳定 本人用的就是celery 3.1.26版本 推荐 pip install celery==3.1.26 

Celery介绍:

上图为celery工作简要流程,原谅我盗的图...原作者po上:https://www.qikqiak.com/

1、application(task producer)"任务的生产者",我们通过代码层面,产生任务然后发送给broker(task queue)

2、celery beat(task scheduler)"任务调度器",常见为生成定时任务

3、broker(task queue)"任务队列",我们需要将任务送往任务队列去,官网强烈推荐的broker有:redis和rabbitmq

4、worker(taks consumer)"任务消费者",在任务送往broker后,worker从中进行操作,完成任务后生成result

5、result 完成任务后产生的结果

Broker的选择:

  broker我们可选的有redis和rabbitmq,官网推荐的两种,我们这里选redis,相对于rabbitmq更加轻量级,安装方便。

  所以我们需要安装redis,redis很容易安装,这里就不细讲了,po上github链接:https://github.com/MicrosoftArchive/redis/releases

  与此同时 celery还需要python的redis依赖库这里注意版本 pip install redis==2.10 最好下2.10版本,这里是为了后续和django联用

  若下最新版本,可能会报以下错:

任务的编写:

  主要的代码层面来了,我们通过流程图知道,我们需要生产任务,目录结构如下图:

        

  1、其中__init__.py是通过启动项目时,选择的配置文件:

1 from celery import Celery
2 
3 app = Celery('demo')
4 app.config_from_object('celery_app.celeryconfig')

  2、celeryconfig.py里面主要是celery的配置:

from datetime import timedelta
from celery.schedules import crontab
# 配置broker为redis
BROKER_URL = 'redis://localhost:6379/1'
# 配置结果存储至redis
CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
# 时区设置
CELERY_TIMEZONE='Asia/Shanghai'
# 导入任务
CELERY_IMPORTS = (
    'celery_app.task1',
    'celery_app.task2',
    )
# 配置定时任务的调度器
CELERYBEAT_SCHEDULE={
    # 任务名字
    'task1':{
        # 任务启动的函数
        'task':'celery_app.task1.add',
        # 定时时间设置,每10秒一次
        'schedule':timedelta(seconds=10),
        # 传递的参数
        'args':(2,8)
    },
    'task2':{
        'task':'celery_app.task2.mul',
        # 定时时间设置,16:45
        'schedule':crontab(hour=16,minute=45),
        'args':(4,5)

    }
}

  3、task1的任务:

import time

from celery_app import app

@app.task
def add(x, y):
    # 阻塞测试
    time.sleep(3)
    return x + y  

  4、 task2的任务:

import time

from celery_app import app

@app.task
def mul(x, y):
    time.sleep(3)
    return x * y

运行任务:

  1、打开redis服务器:

$ .\redis-server.exe .\redis.windows.conf

 

  2、在celery_app文件的上一级 shift+右键 打开命令行窗口,win10打开powershell:

celery worker -A celery_app --pool=solo -l INFO

  此命令打开worer 任务目标为celery_app windows下需要加--pool=solo 日志级别为INFO

  3、然后打开celery beat 启动定时任务,另开一个命令行窗口:

 celery beat -A celery_app -l INFO

   4、结果如下:

  

  可以看见celery beat一直在隔10秒发送任务

  再来看worker:

  

  第一次是处理了4秒 其余是3秒,可以看出windows处理celery还是不太稳定。

  结语:celery是一个强大的库,能让我们处理异步任务,不过最好还是于Linux上运行

   

常见错误:


在linux系统中使用root用户常见错误:
Running a worker with superuser privileges when the
worker accepts messages serialized with pickle is a very bad idea!
If you really want to continue then you have to set the C_FORCE_ROOT environment variable (but please think about this before you do).
 
from  celery import Celery, platforms

platforms.C_FORCE_ROOT= True  #加上这一行
要实现可前端添加定时任务,可以使用 Django 的 celery_beat 库和 MySQL 数据库。 首先,需要安装 celerycelery_beat 库: ``` pip install celery django-celery-beat ``` 然后,在 Django 的 settings.py 文件中设置 celerycelery_beat 的相关配置: ```python # 配置 celery CELERY_BROKER_URL = 'redis://localhost:6379/0' CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' # 配置 celery_beat CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' ``` 接下来,创建一个 app,用于存储定时任务的配置信息。这里假设 app 名称为 `tasks`,在 models.py 中定义一个 `Task` 模型: ```python from django.db import models class Task(models.Model): name = models.CharField(max_length=256) task = models.CharField(max_length=256) args = models.TextField(default='[]') kwargs = models.TextField(default='{}') schedule = models.CharField(max_length=256) ``` 这个模型包含了任务的名称、任务函数、参数、关键字参数和调度器配置信息。 接下来,需要在 app 的 admin.py 文件中注册 `Task` 模型,并自定义 admin 页面的表单。这里使用 `JSONEditorWidget` 来渲染参数和关键字参数的输入框: ```python from django.contrib import admin from django_json_widget.widgets import JSONEditorWidget from .models import Task @admin.register(Task) class TaskAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {'widget': JSONEditorWidget}, } ``` 现在,可以在 admin 页面中添加、删除、修改定时任务的配置信息了。但是,这些配置信息并没有被 celery_beat 调度器使用。为了让 celery_beat 调度器能够使用这些信息,需要在 app 的 `apps.py` 文件中注册定时任务: ```python from django.apps import AppConfig from django.conf import settings from celery import Celery from celery.schedules import crontab from .models import Task class TasksConfig(AppConfig): name = 'tasks' def ready(self): # 创建 celery 实例 app = Celery('tasks', broker=settings.CELERY_BROKER_URL) # 获取所有定时任务配置信息 tasks = Task.objects.all() # 注册定时任务 for task in tasks: app.conf.beat_schedule[task.name] = { 'task': task.task, 'schedule': crontab(task.schedule), 'args': eval(task.args), 'kwargs': eval(task.kwargs), } ``` 这里通过 `AppConfig.ready()` 方法,在 app 启动时注册定时任务。在注册任务时,需要将 `args` 和 `kwargs` 字段的字符串转换成 Python 对象。最后,需要在项目的 __init__.py 文件中配置 app 的默认 AppConfig: ```python default_app_config = 'tasks.apps.TasksConfig' ``` 现在,就可以启动 celerycelery_beat 服务了: ``` celery -A proj worker -l info celery -A proj beat -l info ``` 启动服务后,即可根据 admin 页面上的定时任务配置信息自动调度任务了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值