应用Celery以前,我想你们都已经了解了,什么是Celery,Celery能够作什么,等等一些关于Celery的问题,在这里我就不一一解释了。html
应用以前,要确保环境中添加了Celery包。python
pip install celery
pip install dajngo-celery
安装完成以后咱们还须要安装,Redis or RabbitMQ 须要用到它们来创建消息队列来完成收,发任务。linux
RabbitMQ用户手册:git
https://www.rabbitmq.com/manpages.htmlgithub
Redis中文官网:web
http://www.redis.cn/redis
用以上两种做为消息处理队列均可以,今天咱们来使用Redis来做为队列。shell
本人是用Windows来测试,后边有Linux安装方法。django
下载安装包连接: https://github.com/MSOpenTech/redisjson
打开连接以后,出现以下页面,而后点击 releases
进入到下载页面以后,找到须要下载的版本,测试版本(3.0.500)而后点击版本名称进入当前版本页面。
下载以前须要注意的是,红框中,第一个msi后缀的是微软格式的安装包,第二个zip是压缩包。
下载完成以后,双击msi文件。
安装完成以后,以便从程序后续可以正常工做,添加访问密码,
打开安装目录,找到 redis.windows-service.conf 配置文件,用文本编辑器打开,找到 requirepass字样的地方,添加一行 requirepass 密码。 这是访问redis时须要的密码。通常状况下是能够不用设置的,可是建议仍是设置一下。(我用Notepad++打开的)位置:386
配置完成以后,点击"开始>右击"计算机">"管理", 在左侧找到"计算机管理(本地)">服务和应用程序>服务,再在右侧找到Redis名称的服务,查看启动状态,没有启动则手动启动,通常状况下服务该正常运行了。
Redis服务启动过程当中,报位置错误的状况下,解决办法以下:
一、打开redis安装目录找到redis.windows.conf文件拉到底部,添加 maxmemory 209715200
二、添加完成以后保存退出,打开终端,用命令启动, redis-service.exe redis-windows.conf
三、启动过程当中在报错,错误信息:
[22420] 11 Oct 11:46:23.351 # Server started, Redis version 3.0.500 [22420] 11 Oct 11:46:23.355 # Can't handle RDB format version 7 [22420] 11 Oct 11:46:23.355 # Fatal error loading the DB: Invalid argument. Exiting.
解决办法:
删除全部的dump.rdb文件,重启新启动, redis-service.exe文件,报错缘由,多是rdb文件版本太高或者太低所致使问题出现,
启动成功界面:
redis启动成功以后就不要关闭,应为celery是基于redis来收发任务的, 须要用到redis的队列。
环境到此安装完成以后,开始写个简单的异步任务。
新建立一个Django项目,添加一个应用。
django-admin startproject celery_sq
新建应用
python manage.py startapp app
项目初始化完成以后,打开settings.py文件
必定要将celery导入进去,才可使用。紧接着导入须要用到的模块。
from celery.schedules import crontab from celery.schedules import timedelta
在settings文件拉到底部,添加如下代码。
import djcelery djcelery.setup_loader() BROKER_URL = 'redis://127.0.0.1:6379/' CELERY_IMPORTS = ('app.tasks') CELERY_TIMEZONE = 'Asia/Shanghai' CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
以上代码添加完成以后再同级目录下建立 celery.py
from __future__ import absolute_import, unicode_literals # -*- coding: utf-8 -*- __author__ = 'YongCong Wu' # @Time : 2018/10/9 15:52 # @Email : : 1922878025@qq.com import os from celery import Celery from django.conf import settings # set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celery_sq.settings') app = Celery('celery_sq') # Using a string here means the worker don'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') # Load task modules from all registered Django app configs. app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) @app.task(bind=True) def debug_task(self): print('Request: {0!r}'.format(self.request))
在app目录下添加tasks.py文件, 注意:一个应用下只能添加一个tasks.py 一个py一遍可写多个任务。
from __future__ import absolute_import # -*- coding: utf-8 -*- __author__ = 'YongCong Wu' # @Time : 2018/10/9 16:10 # @Email : : 1922878025@qq.com from celery_sq.celery import app @app.task def add(x, y): return x + y
添加完成以后,在app同级目录下的views文件里边添加函数。
from django.shortcuts import render, HttpResponse # Create your views here. from .tasks import add import json def add_handler(request): x = request.GET.get('x', 1) y = request.GET.get('y', 1) result = add(int(x), int(y)) return HttpResponse(json.dumps({'result': result}))
添加urls.py
# -*- coding: utf-8 -*- __author__ = 'YongCong Wu' # @Time : 2018/10/10 14:46 # @Email : : 1922878025@qq.com from django.conf.urls import include, url from django.contrib import admin from app import views urlpatterns = [ url(r'^add/', views.add_handler), ]
app 中的url添加完成以后须要在celery_sq目录下的urls.py中添加。
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^home/', include('app.urls')), # 添加这个 ]
添加完成以后就开始测试咱们的项目,现将项目运行起来。
python manage.pu runserver
项目启动完成以后,从新打开一个终端,进入项目目录,启动django celery 服务。
python manage.py celery worker --loglevel=info
见到这个界面,就说明django celery已经启动成功了,接下来就开始测试咱们的异步任务了。
测试地址端口可自行修改,根据本身端口来设置: http://127.0.0.1:9000/home/add/?x=5&y=5
如今每家公司,有各类各样的需求,有的须要定时去查找数据等等,一些定时的功能。接下来,咱们就用Celery来完成一个定时写入txt文件的一个任务。
app/tasks.py文件添加如下代码。
from celery import shared_task @shared_task def hello_world(): with open("output.txt", "a") as f: f.write("hello world") f.write("\n")
在settings.py下添加
CELERYBEAT_SCHEDULE = { # 定时器策略 # 定时任务一: 每隔30s运行一次 u'测试定时器1': { "task": "app.tasks.tsend_email", # "schedule": crontab(minute='*/2'), # or 'schedule': timedelta(seconds=3), "schedule": timedelta(seconds=30), "args": (), }, }
此时tasks.py文件里边有一个定时tasks。
参数定义:
days 天
seconds 秒
microseconds 微秒
milliseconds 毫秒
minutes 分
hours 小时
month_of_year 月份
day_of_month 日期
day_of_week 周
hour 小时
minute 分钟
定时任务添加完成以后,启动celery beat, celery启动了一个beat进程一直在不断的判断是否有任务须要执行。
celery -A celery_sq beat -l info
从新打开终端,输入以上命令启动 celery beat, 启动成功以后看到以下页面。
任务成功执行以后状态
到此为止,在windows下,测试异步任务和定时任务已经完成,那么有个问题,在windows下执行一下celery须要打开这么多的终端窗口,哪用linux部署项目的时候该怎么办呢,接下来,咱们就在linux下部署。咱们用守护进程的方式来完成。
Linux默认Python环境是2.7,须要自行下载Pyhton3.5。(安装过程自行百度)
linux下,咱们通常用守护进程的方式来启动 Celery ,否则总不能在打开不少窗口一个窗口启动一个beat等等吧。
在linux下使用supervisor来守护进程。
supervisor官网:
安装Redis:
wget http://download.redis.io/releases/redis-2.8.3.tar.gz
安装完成以后须要解压,编译。依次按照如下命令执行。
tar xzf redis-2.8.3.tar.gz
cd redis-2.8.3
make && make install
安装supervisor
pip install supervisor
supervisor配置
咱们使用echo_supervisord_conf命令来获得supervisor配置模板,打开终端shell输入如下命令。
echo_supervisord_conf > supervisord.conf
接下来编辑 supervisord.conf文件
vim supervisord.conf
修改include分发ini文件目录。
配置完成以后建立conf.d目录
mkdir conf.d
建立完成以后进入目录,建立ini文件将如下配置写入文件中。
测试添加ini文件是否读取。
在任意目录下建立hello.py文件,添加如下代码,来进行测试。
import time import sys while True: print("test data\n") sys.stdout.flush() time.sleep(1)
添加完成以后保存,用 python 文件名称 来执行py文件是否出错。正确结果:
测试完成以后开始为hello.py添加进程守护。
进入conf.d目录添加 hello.ini文件。将如下配置写入文件。
[program:hello] 名字随意,不要重复 command=python /home/hello.py stdout_Logfile=/home/celery_log/hello.log stderr_logfile=/home/celery_log/hello_error.log
运行supervisord
supervisord -c /home/supervisor/supervisord.conf
运行hello进程
supervisordctl -c /home/supervisor/supervisord.conf 运行所有 supervisordctl -c /home/supervisor/supervisord.conf start heelo 指定运行 supervisordctl -c /home/supervisor/supervisord.conf stop heelo 指定中止 参数: start status stop restart 启动,状态, 中止, 重启
以上图片是启动成功以后的状态。
测试完成以后就开始配置Redis。
添加redis.ini文件,将如下内容添加。
[program:redis] command=/home/redis-4.0.1/src/redis-server autostart=true autorestart=true startsecs=3 stdout_Logfile=/home/celery_Log/redis.log 标准日志输出 stderr_logfile=/home/celery_log/redis_error.log 错误日志输出
添加完成以后须要使用如下命令来加载进程。
supervisorctl reload
因为 supervisor 管理的进程不能设置为 daemon 模式,故若是 Redis 没法正常启动,能够查看一下 Redis 的配置,并将daemonize
选项设置为 no。
daemonize no
到文件的地步添加以下信息
[program:celery] # 启动命令入口 command=/var/www/newweb/venv/bin/celery worker -A celery_worker.celery --loglevel=info # 命令程序所在目录 directory=/var/www/newweb/ # 运行命令的用户名 user=root autostart=true autorestart=true # 日志地址 stdout_logfile=/var/log/newymw2.0/supervisor/newymw2.0_celery.log
另外在celery.worker下设置beat定时任务的进程
[program:celery.beat] ;指定运行目录 directory=/home/xxx/webapps/yshblog_app/yshblog ;运行目录下执行命令 command=celery -A yshblog worker --loglevel info --logfile celery_beat.log ;启动设置 numprocs=1 ;进程数 autostart=true ;当supervisor启动时,程序将会自动启动 autorestart=true ;自动重启 ;中止信号 stopsignal=INT
worker和beat都设置好以后就能够配置redis了。
[program:redis] ;指定运行目录 directory=~/webapps/yshblog_app/lib/redis-3.2.8/ ;执行命令(redis-server redis配置文件路径) command=redis-server redis.conf ;启动设置 numprocs=1 ;进程数 autostart=true ;当supervisor启动时,程序将会自动启动 autorestart=true ;自动重启 ;中止信号 stopsignal=INT
启动supervisord
supervisord -c /home/supervisor/supervisor.conf
查看进程状态
supervisorctl -c /home/supervisor/supervisor.conf status all
加载supervisord,在新添加进程的状况下使用加载,新添加一个,加载一次。
supervisorctl -c /home/supervisor/supervisor.conf reload
运行测试celery过程当中若是出现以下错误(celery不能用root用户来启动),按照如下步骤添加,便可解决
测试命令:
celery -A celery_sq worker -l info
错误信息:
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). User information: uid=0 euid=0 gid=0 egid=0
解决办法:
celery.py添加以下代码 from celery import Celery, platforms platforms.C_FORCE_ROOT = True
测试成功页面
测试成功以后开始测试beat
测试beat命令:
celery -A celery_sq beat -l info
测试成功页面:
成功以后守护进程就是这个样子的。
[program:redis] command=/home/redis-4.0.1/src/redis-server autostart=true autorestart=true startsecs=3 stdout_Logfile=/home/celery_log/redis.log stderr_logfile=/home/celery_log/redis_error.log
[program:celeryworker] directory=/root/.pyenv/versions/Celery_prj/celery_sq command=celery -A celery_sq worker -l info autostart=true autorestart=true stdout_logfile=/home/celery_log/celery_worker.log stderr_logfile=/home/celery_log/celery_worker_error.log
[program:celerybeat] directory=/root/.pyenv/versions/Celery_prj/celery_sq command=celery -A celery_sq beat -l info autostart=true autorestart=true stdout_logfile=/home/celery_log/celery_beat.log stderr_logfile=/home/celery_log/celery_beat_error.log
到此为止,windows以及Linux下django-celery守护进程以及配置所有完成, 以上由本人所有亲测,一步一步写进博客,若有问题,请及时提出。见到第一时间修改。/抱拳