celery文档参考:http://docs.jinkan.org/docs/celery/
同步请求:所有逻辑处理、数据计算任务在View中处理完毕后返回response。在View处理任务时用户处于等待状态,直到页面返回结果。异步请求:View中先返回response,再在后台处理任务。用户无需等待,可以继续浏览网站。当任务处理完成时,我们可以再告知用户。
Celery简介
Celery是由Python开发、简单、灵活、可靠的分布式任务队列,其本质是生产者消费者模型,
生产者发送任务到消息队列,消费者负责处理任务。Celery侧重于实时操作,但对调度支持也很好,
其每天可以处理数以百万计的任务。
特点:
简单:熟 悉celery的工作流程后,配置使用简单高可用:当任务执行失败或执行过程中发生连接中断,celery会自动尝试重新执行任务快速:一个单进程的celery每分钟可处理上百万个任务灵活:几乎celery的各个组件都可以被扩展及自定制
应用场景举例
1.耗时任务:当用户在网站进行某个操作需要很长时间完成时,我们可以将这种操作交给Celery执行,直接返回给用户,等到Celery执行完成以后通知用户,大大提好网站的并发以及用户的体验感。2.任务场景:比如在运维场景下需要批量在几百台机器执行某些命令或者任务,此时Celery可以轻松搞定。3.定时任务:向定时导数据报表、定时发送通知类似场景,虽然Linux的计划任务可以帮我实现,但是非常不利于管理,而Celery可以提供管理接口和丰富的API。
工作原理
任务模块Task包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往消息队列,而定时任务由Celery Beat进程周期性地将任务发往消息队列;
任务执行单元Worker实时监视消息队列获取队列中的任务执行;
Woker执行完任务后将结果保存在Backend中;
Celery组成模块
1.任务模块 Task包含异步任务和定时任务。其中,异步任务通常在业务逻辑中被触发并发往任务队列,而定时任务由 Celery Beat 进程周期性地将任务发往任务队列2.消息中间件Broker任务调度队列,接收任务生产者发来的消息(即任务),将任务存入队列。Celery 本身不提供队列服务,支持RabbitMQ、Redis、Amazon SQS、MongoDB、Memcached 等,官方推荐RabbitMQ。3.任务执行单元WorkerWorker是任务执行单元,负责从消息队列中取出任务执行,它可以启动一个或者多个,也可以启动在不同的机器节点,这就是其实现分布式的核心。4.结果存储Backend用于存储任务的执行结果,以供查询。同消息中间件一样,支持:RabbitMQ、 Redis、Memcached,SQLAlchemy, Django ORM、Apache Cassandra、Elasticsearch。
使用
1.配置settings.py# 配置异步任务BROKER_URL = 'redis://127.0.0.1:6379/1'# 存储结果并跟踪结果CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1'# 消息格式CELERY_ACCEPT_CONNECT=['application/json',]CELERY_TASK_SERIALIZER = 'json'CELERY_RESULT_SERIALIZER = 'json'# celery的时区CELERY_TIMEZONE = TIME_ZONE2.下载安装包pip install redis==2.10.6(版本过高报错:AttributeError:'str' object has no attribute 'items')pip install celerypip install celery-with-redis3.编写celery文件(和settings.py同级)import osfrom celery import Celeryfrom djangoday10.settings import BROKER_URL, CELERY_RESULT_BACKENDproject_name = os.path.split(os.path.abspath('.'))[-1]project_settings = '%s.settings' % project_name# 设置环境变量os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)# 实例化celeryapp = Celery(project_name)# 使用django的配置文件进行配置app.config_from_object('django.conf:settings')4.修改__init__.pyfrom __future__ import absolute_import from .celery import app as celery_app5.在需要的app中定义tasks.py在该文件中定义任务@shared_taskdef sendmail(uid, email):subject = '异步发送邮件测试'message = "亲爱的用户你好!点击激活用户<a href='http://127.0.0.1:8000/active/%s'> 激活 </a>" % uidsend_mail(subject, message='', from_email=EMAIL_HOST_USER, recipient_list=[email], html_message=message)6. 调用任务:# 此时启动异步发送邮件,delay是注册celery异步任务的关键点result = sendmail.delay(uid,email)7. 测试异步:启动异步workercelery -A projectname worker -l infopython manage.py celery worker --loglevel=infofrom kombu.async.timer import Entry, Timer as Schedule, to_timestamp, logger^
SyntaxError: invalid syntax原因: async 在 python3.7已经是关键字了,但是celery4.4.6版本没有更新导致的。此问题将在下一个版本修复。解决办法: 将celery文件中的async命名为其他变量名/ 或者降低python版本3.7之下的8.通过可视化的flower查看celery的执行情况:pip install flowerflower -A djangoday10 --port=5500http://localhost:5500 打开查看
日志:
https://www.cnblogs.com/luohengstudy/p/6890395.html
1.配置
LOG_PATH=os.path.join(BASE_DIR,'log')
if not os.path.exists(LOG_PATH)os.mkdir(LOG_PATH)
LOGGING = {# version只能为1,定义了配置文件的版本,当前版本号为1.0"version": 1,# True表示禁用logger"disable_existing_loggers": False,# 格式化'formatters': {'default': {'format': '%(levelno)s %(funcName)s %(module)s %(asctime)s %(message)s '},'simple': {'format': '%(levelno)s %(module)s %(created)s %(message)s'}},
'handlers': {'user_handlers': {'level': 'DEBUG',# 日志文件指定为5M, 超过5m重新命名,然后写入新的日志文件'class': 'logging.handlers.RotatingFileHandler',# 指定文件大小'maxBytes': 5 * 1024,# 指定文件地址'filename': '%s/log.txt' % LOG_PATH,'formatter': 'default'},# 'uauth_handlers': {# 'level': 'DEBUG',# # 日志文件指定为5M, 超过5m重新命名,然后写入新的日志文件# 'class': 'logging.handlers.RotatingFileHandler',# # 指定文件大小# 'maxBytes': 5 * 1024 * 1024,# # 指定文件地址# 'filename': '%s/uauth.txt' % LOG_PATH,# 'formatter': 'simple'# }
},
'loggers': {'user': {'handlers': ['user_handlers'],'level': 'INFO'},# 'auth': {# 'handlers': ['uauth_handlers'],# 'level': 'INFO'# }
},'filters': {}
}
2.使用
logger = logging.getLogger('user')
logger.info(日志的内容) ----》 info级别的日志内容
logger.error(。。。。)