celery + django附有代码和注释

Celery是什么

工作模式

使用场景

手册:http://docs.celeryproject.org

一. 环境安装

    windows下安装包(4版本已经移除对windows的支持,所以只能使用低版本的)

        pip install celery==3.1.25

        pip install celery-with-redis

    Linux直接默认安装最新版本

  • celery的使用

参考测试1文件

    1. 基本配置

        1. 创建app

            在__init__.py中创建

                from celery import Celery

 # 创建 Celery 实例

                app = Celery(app名称)                        

                 # 通过 Celery 实例加载配置模块

app.config_from_object('当前文件夹.配置文件')  

        2. 任务的书写,看具体要实现的功能来书写

        3. 配置文件的书写

            BROKER_URL = "redis://localhost:6379/0"  # 指定 Broker

            CELERY_RESULT_BACKEND = "redis://localhost:6379/1"  # 指定 Backend

            CELERY_TIMEZONE = 'Asia/Shanghai'  # 指定时区,默认是 UTC

BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 43200}

            # CELERY_TIMEZONE='UTC'

            CELERY_IMPORTS = (  # 指定导入的任务模块

                'celery_app.task1',

                'celery_app.task2'

            )

    2. 手动驱动任务

        在app配置的文件夹的当前目录写一个执行文件client.py

            例如:

                from celery_app import task1

                from celery_app import task2

                task1.add.apply_async(args=[2, 8])  # 也可用 task1.add.delay(2, 8)

                task2.multiply.apply_async(args=[3, 7])  # 也可用 task2.multiply.delay(3, 7)

                print('hello world')

                # countdown:指定多少秒后执行任务

                task1.add.apply_async(args=(2, 23), countdown=5)  # 5 秒后执行任务

                task1.add.apply_async(args=[6, 7], expires=10)  # 10 秒后过期

        执行方式:

            终端上先找到app文件夹目录运行:celery -A celery_app worker --loglevel=info

            再执行client.py

    3. bast定时任务驱动任务(可某个时间调度,也可以每多少秒)

        1. 在配置文件上添加调度

            from datetime import timedelta

            from celery.schedules import crontab

            # schedules

            CELERYBEAT_SCHEDULE = {

                'add-every-30-seconds': {

                    'task': 'celery_app.task1.add',

                    'schedule': timedelta(seconds=3),  # 每 30 秒执行一次

                    'args': (5, 8)  # 任务函数参数

                },

                'multiply-at-some-time': {

                    'task': 'celery_app.task2.multiply',

                    'schedule': crontab(hour=9, minute=50),  # 每天早上 9 点 50 分执行一次

                    'args': (3, 7)  # 任务函数参数

                }

            }

        2. 终端运行方式:

            celery beat -A app目录文件夹 -l INFO (celery beat -A celery_app -l INFO)

            celery worker -A app目录文件夹 -l INFO (celery worker -A celery_app -l INFO)

"-B"参数告诉celery在启动worker时同时启动celery beat, 并使用统一进程, 以便执行定期

Direct Exchange

如其名,直接交换,也就是指定一个消息被那个队列接收, 这个消息被celerybeat定义个一个routing key,如果你发送给交换机并且那个队列绑定的bindingkey 那么就会直接转给这个队列

Topic Exchange

你设想一下这样的环境(我举例个小型的应该用场景): 你有三个队列和三个消息, A消息可能希望被X,Y处理,B消息你希望被,X,Z处理,C消息你希望被Y,Z处理.并且这个不是队列的不同而是消息希望被相关的队列都去执行,看一张图可能更好理解:

对,Topic可以根据同类的属性进程通配, 你只需要routing key有’.’分割:比如上图中的usa.news, usa.weather, europe.news, europe.weather

Fanout Exchange

先想一下广播的概念, 在设想你有某个任务,相当耗费时间,但是却要求很高的实时性,那么你可以需要多台服务器的多个workers一起工作,每个服务器负担其中的一部分,但是celerybeat只会生成一个任务,被某个worker取走就没了, 所以你需要让每个服务器的队列都要收到这个消息.这里很需要注意的是:你的fanout类型的消息在生成的时候为多份,每个队列一份,而不是一个消息发送给单一队列的次数

  • Django中使用celery

参照django_celery的设置

Redis==2.10.6 celery=3.1.15

django-celery

  1. Install: pip install django-celery
  2. Worker: python manage.py celery worker -Q queue
  3. Beat: python manage.py celery beat

from celery import Celery, platforms

platforms.C_FORCE_ROOT = True  #加上这一行

工程中创建celeryconfig.py

# coding=utf-8

import djcelery

from celery import platforms

platforms.C_FORCE_ROOT = True

djcelery.setup_loader()

CELERY_IMPORTS = {

    'course.tasks'

}

BROKER_BACKEND = 'redis'

BROKER_URL = "redis://localhost:6379/0"  # 指定 Broker

CELERY_RESULT_BACKEND = "redis://localhost:6379/1"  # 指定 Backend

# 有些情况可以防止死锁

CELERYD_FORCE_EXECV = True

# 设置并发worker数量

CELERYD_CONCURRENCY = 2

# 允许重试

CELERY_ACKS_LATE = True

# 每个worker最多执行多少个任务被销毁,可以防止内存销毁

CELERYD_MAX_TASKS_PER_CHILD = 100

# 单个任务最大运行时间

CELERYD_TASK_TIME_LIMIT = 12 * 30

CELERY_DEFAULT_QUEUE = "work_queue" # 默认的队列,如果一个消息不符合其他的队列就会放在默认队列里面

CELERY_QUEUES = {

    "beat_tasks": {

        "exchange": "beat_tasks",

        "exchange_type": "direct",

        "binding_key": "beat_tasks"

    },

"work_queue": {         

"binding_key": "work_queue.#",

        "exchange": "work_queue",

        "exchange_type": "direct",

    },

}

from datetime import timedelta

CELERYBEAT_SCHEDULE = {

    'task1':{

        'task': 'course-task',

        'schedule': timedelta(seconds=5),

        'options':{

            'queue':'beat_tasks'

        }

    }

}

Settings.py

INSTALLED_APPS = (

    'djcelery',

)

# Celery

from .celeryconfig import *

Views.py

from django.shortcuts import render

from course.tasks import CourseTask

from django.http import JsonResponse

# Create your views here.

def do(request):

    print 'start'

    CourseTask.apply_async(args=[2, 8], queue="import_task")

    print 'end'

    return JsonResponse({'result':'ok'})

App中创建tasks.py

# coding=utf-8

from celery.task import Task

import time

class CourseTask(Task):

    name = 'course-task'

    def run(self, *args, **kwargs):

        print 'start course task'

        time.sleep(4)

        print 'args={}, kwargs={}'.format(args, kwargs)

        print 'end course task'

  • Celery监控工具flower

 pip install flower==0.9

python manage.py celery flower

celery flower --address=0.0.0.0 --port=5555 --broker=xxx --basic_auth=imooc:imooc

  • Supervisor部署celery

pip install supervisor

Start: supervisord -c supervisord.conf

Tool: supervisorctl (命令:status,update,stop)

复制 echo_supervisord_conf > supervisord.conf

[include]

files = *.ini

[supervisorctl]

serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket

[inet_http_server]         ; inet (TCP) server disabled by default

port=*:9001        ; ip_address:port specifier, *:port for all iface

username=root              ; default is no username (open server)

password=12321hjz           ; default is no password (open server)

supervisor_celery_work.ini

[program:celery_course]

command=python manage.py celery worker -l INFO

directory=/home/tarena/PycharmProjects/celery_course

# enviroment=PATH="/usr/lib/python2.7/dist-packages"

stdout_logfile=/home/tarena/PycharmProjects/celery_course/logs/celery_work.log

stderr_logfile=/home/tarena/PycharmProjects/celery_course/logs/celery_work_err.log

autostart=true

autorestart=true

startsecs=10

stopwatisecs=60

priority=998

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值