一、环境(django+celery+redis+flower)
第一步:安装环境
brew install Redis
pip install -U "celery[redis]"
(同时安装celery-4.4.1 #redis的库、vine-1.3.0、billiard-3.6.3.0、kombu-4.6.8、redis-3.4.1、amqp-2.5.2)(拓展:pip的参数[-i]:指定库的安装源[-U]升级原来已经安装的包)
pip install flower
django环境的安装不介绍
第二步:介绍软件
celery:
celery是一个分布式异步任务队列管理工具。
flower:
管控任务的执行状态和查看任务执行结果,界面化管理。flower作为web页面来管理celery后台任务,和任务队列是隔离的,flower的运行与否并不会影响到任务队列的真正执行,但是flower中可以通过API接口来管理celery中的任务执行。
浏览器:127.0.0.1:5555
flower说明:
Dashboard 页面是展示异步任务队列的主要情况。
Tasks 页面是展示所有worker接收到的任务的处理情况。
Broker 页面展示的是celery连接消息队列的信息,包括消息队列的访问URL。
Monitor 页面展示的是celery后台任务的曲线展示状况。
二、应用实例
第一步:创建django的测试使用app
django项目名称为guest
python manage.py startapp celeryApp,在settings中添加应用
第二步:创建celery案例
(1)、配置celery
guest/guest/settings.py
#celery_config
#消息中间件,消息代理,用于发布者传递消息给消费者 端口 数据库号
BROKER_URL = 'redis://127.0.0.1:6379/0'
#消息结果返回中间件,用于存储任务执行结果
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
#允许的内容类型
CELERY_ACCEPT_CONTENT = ['application/json']
#任务的序列化方式
CELERY_TASK_SERIALIZER = 'json'
#任务结果的序列化方式
CELERY_RESULT_SERIALIZER = 'json'
#时区,定时任务使用
CELERY_TIMEZONE = 'Asia/Shanghai'
guest/guest/celery.py
#coding=utf-8
# absolute_import绝对引用申明
# unicode_literals显式将出现的所有字符串转为unicode类型,django rest framework的接口都是返回Unicode类型字符串,并且调用len()和遍历也是以字符为单位。
from __future__ import absolute_import, unicode_literals
import os
from django.conf import settings
from celery import Celery
#设置django的配置文件,guest为django的项目名
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'guest.settings')
#实例化celery
app = Celery('guest', broker='redis://127.0.0.1:6379/0') #创建celery实例
app.config_from_object('django.conf:settings')
#搜索所有app中的tasks lambda定义一个匿名函数
app.autodiscover_tasks(lambda:settings.INSTALLED_APPS)
guest/guest/__init__.py
#coding=utf-8
from __future__ import absolute_import
#确保django启动时启动celery
from .celery import app as celery_app
__all__ = ['celery_app']
(2)、创建celery案例
案例内容:一个在后台执行x+y的一个任务,函数名称是add。
guest/celeryApp/task.py
#coding=utf-8
from __future__ import absolute_import
from celery import task
import time
#关于task,并不是一定要把所有的task放在tasks.py,可以放在其他类里面,只要在函数上加@task即可
@task
def add(x, y):
print "任务开始"
print x+y
time.sleep(10)
print "任务结束"
guest/celeryApp/view.py
from celeryApp import tasks
# Create your views here.
#class TestView(View):
def get(request):
#下面两句交celery处理,django直接处理下面逻辑
tasks.add.delay(1,2)
result ={'code':0,'msg':'后台任务'}
if request.user.is_authenticated():
username = request.user.username
else:
messages.add_message(request, messages.WARNING, '未登录')
messages.add_message(request, messages.WARNING, "celery")
template = get_template('celery.html')
html = template.render(context=locals(), request=request)
return HttpResponse(html)
guest/celeryApp/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from celeryApp import views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#celery
url(r'^add/$', views.get),
]
#让meida内的图像文件不经过python manage.py collectstatic的步骤直接显示
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
guest/guest/urls.py
url(r'^celeryApp/', include('celeryApp.urls'), name='celeryApp'),
guest/celeryApp/templates/celery.html
{% extends "base.html" %}
{% block title %}
{% endblock %}
{% block content %}
<div class='row'>
<div class='panel panel-default'>
<div class='panel-heading' align='center'>
<h4>测试</h4>
</div>
<div class='panel-body'>
{{result}}
</div>
</div>
</div>
{% endblock %}
django主页html文件增加:
<a href="/celeryApp/add/">celery</a></br>
(3)、启动测试
启动django:python manage.py runserver 0.0.0.0:80000
启动celery的borker(redis启动):redis-server
flower启动:flower --broker=redis://127.0.0.1:6379/ --address=127.0.0.1 --port=5555
启动celery的worker任务:celery -A guest worker --pool=solo -l info(guest是django的项目名称)
(4)、效果
点击django主页的celery按钮,执行。
celery的worker任务输出:
[2020-03-06 20:50:39,257: WARNING/MainProcess] 任务开始
[2020-03-06 20:50:39,257: WARNING/MainProcess] 3
[2020-03-06 20:50:49,260: WARNING/MainProcess] 任务结束
[2020-03-06 20:50:49,264: INFO/MainProcess] Task celeryApp.tasks.add[447d35ae-7c07-4ed3-9d0a-a7ce279e3057] succeeded in 10.00744048s: None
django网页:
http://192.168.2.102:8000/celeryApp/add/
flower监控:
http://127.0.0.1:5555/dashboard
三、遇到的问题:
1、Error 61 connecting to 127.0.0.1:6379. Connection refused.
原因:这个错误是因为客户端找不到服务端,redis
2、在mac上使用brew安装软件时,一般都会出现“Updating Homebrew...”且等待时间长。
原因:mac尝试访问国外的源,进行替换即可。