# 原创,转载请留言联系

在用django做项目的时候,做到注册模块时,需要发送短信验证码。本来简简单单的做好了,后来优化的时候发现,发送短信验证码的时候需要一点时间,在这个时间之内程序是阻塞的,用户体验太不好了。往往都是点击获取验证码后,过了几秒钟之后才显示发送成功。所以想到了用celery异步任务队列优化一下。

celery原理详解:https://www.cnblogs.com/chichung/p/9957763.html

通过celery可以把发短信验证码的这部分交给其他进程来做,视图继续往下执行,那么当用户点击发送验证码的时候,就能马上显示发送成功了。

还是先看一下大体流程图:

  • 步骤:

1.安装celery

pip install celery

2.创建celery存放文件件

一般来用,celery会独立放在项目文件下。

创建文件夹如下:

celery_tasks/
├── __init__.py
├── main.py    # 创建celery应用的地方
└── sms
    ├── __init__.py
    └── tasks.py    # 任务函数存放的地方,注意,tasks这个名字是固定的,不能改,如果改的话worker找不到!

3.创建celery应用

在main.py上:

from celery import Celery

# 第一个参数,是应用名,可以随便写
# 第二个参数,是中间人broker(用来保存任务)的储存地方,保存在本机的redis的15号库
celery_app = Celery("meiduo",broker="redis://127.0.0.1:6379/15")

4.创建celery任务

@celery.task  # 装饰器表示把这个函数标记为celery的任务函数
def send_sms(mobile,sms_codes):
# 下面是实现短信验证码发送的逻辑
result = CCP().send_template_sms(mobile, [sms_codes, constants.SMS_CODE_REDIS_EXPIRES // 60],
constants.SEND_SMS_TEMPLATE_ID)

5.设置django配置文件的路径。

在main.py上:

# 设置django配置文件的路径(需要在创建celery应用之前设置),设置了配置文件,celery才知道django的导包路径是怎么样的!
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meiduo_mall.settings.dev") # 第一个参数,是应用名,可以随便写
# 第二个参数,是中间人broker(用来保存任务)的储存地方,保存在本机的redis的15号库
celery_app = Celery("meiduo",broker="redis://127.0.0.1:6379/15")

6.指定用celery执行的任务函数的位置

# 设置django配置文件的路径(需要在创建celery应用之前设置),设置了配置文件,celery才知道django的导包路径是怎么样的!
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meiduo_mall.settings.dev") # 第一个参数,是应用名,可以随便写
# 第二个参数,是中间人broker(用来保存任务)的储存地方,保存在本机的redis的15号库
celery_app = Celery("meiduo",broker="redis://127.0.0.1:6379/15") # 指定任务函数的文件夹位置,表示从哪些位置找到任务函数。
# 查找的方法是,找到sms文件夹,然后就会自动去找tasks.py。这就是为什么task.py不能乱起名的原因。然后找到task.py里面有celery应用装饰的函数。
celery_app.autodiscover_tasks(['celery_tasks.sms'])

7.启动worker进程

celery -A celery应用所在py文件 worker -l info
    例: celery -A celery_tasks.main worker -l info

服务器启动后能够看到如下任务,worker进程才能正常工作处理任务
    [tasks]
      . celery_tasks.sms.tasks.send_sms_code

8.通过装饰器name参数自定义任务名(可选)

@celery_app.task(name='send_sms_code')
    def send_sms_code(mobile, sms_code):
        ...
        
    自定义完后,启动celery工作进程在输出信息中可以看到如下任务名
    [tasks]
      . send_sms_code

9.发送任务:  调用delay方法发送异步任务

在视图可以调用任务函数进行发送任务了,任务会储存在中间人broker,woker空闲时就会取出并执行。

class SmsCodesView(APIView):
def get(self,request,mobile):
...
# 发送验证码
send_sms.delay(mobile,sms_codes) ...

10.worker执行任务

示例:

[2017-01-22 xxxx: INFO/ForkPoolWorker-2] Task         
celery_tasks.sms.tasks.send_sms_code[2f4dc753-3cd5-4eaa-994a-d944c45a857c]
succeeded in 3.2456164589966647s: None

  • 拓展

1.中间人broker是怎么存储任务的?

使用json存储:保存了任务函数标识,任务函数名,调用参数等

2.如果任务函数有返回值,应该怎么取?

(1)首先,需要有一个地方存储任务函数的返回值。这里选择redis的14号库。

修改main.py

celery_app = Celery('meiduo',broker='redis://127.0.0.1:6379/15',backend='redis://127.0.0.1:6379/14')

这时候,worker执行完任务函数后,会把任务函数的返回值存储在redis上。

(2)怎么把返回值取出来用呢?

假设发送短信这个任务函数有返回值,如果是0就是发送成功,是-1就是发送失败。

result = send_sms.delay(mobile,sms_codes)

应该怎么拿到result的值呢?

其实,当worker执行完之后,result.ready()的值是True。未执行完是False。

当执行会之后(result.ready=True),可以用get方法取出返回值。

result.get()

(3)怎么把配置文件独立在一个文件里面呢?

1. 在celery_tasks包下创建配置文件 config.py, 并定义配置如下
    broker_url ='redis://127.0.0.1:6379/15'
    backend_url='redis://127.0.0.1:6379/14'
    
2. 加载配置文件
    celery_app = Celery('meiduo')  # 把配置都放到了config.py文件
    celery_app.config_from_object('celery_tasks.config')

django使用celery进行耗时任务的优化的更多相关文章

  1. django集成celery

    Celery是一个基于分布式消息传递的开源异步任务队列,在django实际应用场景下,往往有一些较为耗时,但并不需要返回值的任务, 例如发送邮件,更新我们自己的统计数据库,这时我们可以将这些任务交由c ...

  2. Django使用Celery进行异步任务

    Celery Celery是一个功能完备即插即用的异步任务队列系统.它适用于异步处理问题,当发送邮件.或者文件上传, 图像处理等等一些比较耗时的操作,我们可将其异步执行,这样用户不需要等待很久,提高用 ...

  3. Django中Celery的实现介绍(一)

    Django中Celery的实现 Celery官网http://www.celeryproject.org/ 学习资料:http://docs.jinkan.org/docs/celery/ Cele ...

  4. django集成celery之callback方式link_error和on_failure

    在使用django集成celery进行了异步调度任务之后,如果想对失败的任务进行跟踪或者告警,怎么做? 这里提供一个亲测的方法. 1.任务callback 假如你想在任务执行失败的时候,打印错误信息并 ...

  5. django配置celery

    官网详尽的django结合celery的配置步骤 在django项目settings.py所在的目录中新建一个celery.py,内容如下 from __future__ import absolut ...

  6. Django中Celery http请求异步处理(四)

    Django中Celery http请求异步处理 本章延续celery之前的系列 1.settings配置 2.编写task jib_update_task任务为更新salt jid数据 3.url设 ...

  7. django、celery异步发邮件

    django.celery异步发邮件 django自带的send_mail发邮件功能执行发邮件功能会因为网络的原因造成花费的时间过长,为了解决这个问题,可以用celery + redis代替 安装包: ...

  8. python django与celery的集成

    一.celery与django 关于celery介绍和使用可以查看上篇Python中任务队列-芹菜celery的使用 关于django的介绍和使用可查看python django框架+vue.js前后 ...

  9. Django 使用celery任务队列的配置

    celery 情景:用户发起request,并等待response返回.在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件.手机验证码等. 使用 ...

随机推荐

  1. tinymce4.x 上传本地图片 (转载)

    转载自:http://www.cnblogs.com/fhen/p/5809514.html tinymce4.x 上传本地图片   tinymce是一款挺不错的html文本编辑器.但是添加图片是直接 ...

  2. 简易cmake多文件多目录工程模板

    今天心血来潮,想在服务器上试试写libevent的工程是什么感受,那第一步就是学会怎么用cmake建工程,之前也没接触过cmake,然后一上午,比较懵逼,下午看实验室哥们给的一个教程,然后,慢慢理解C ...

  3. BZOJ 2756 SCOI2012 奇怪的游戏 最大流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2756 Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N ...

  4. SPOJ 1812 Longest Common Substring II(后缀自动机)(LCS2)

    A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the s ...

  5. 数论初步——Eratosthenes筛法

    具体内容见紫书p312-p313 一.用Eratosthenes筛法构造1~n的素数表 思想:对于不超过n的每个非负整数p,删除2p,3p,4p…,当处理完所有的数后,还没有被删除的就是素数. 代码: ...

  6. 有向图的强连通分量——kosaraju算法

    一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量

  7. cocos2d-x环境搭建 摘自百度文库

    cocos2d-x环境搭建 引言:笔者在网上寻觅了很多资料,最终发现了这份实际可用的文档,供大家参考.源地址:http://wenku.baidu.com/view/93f7b0f1102de2bd9 ...

  8. POI 导入 一直报400问题

    排查过程:1.400一般都是参数或者请求不对,但是我这个情况是本地好用,只是服务器有问题,所以排除了传值的格式等问题. 2.服务器和本地网络隔离,所以没办法比较代码,分两次全量覆盖了html和js部分 ...

  9. LoadRunner系统架构简介与运行原理

    1.LoadRunner系统架构简介 LoadRunner是通过创建虚拟用户来代替真实实际用户来操作客户端软件比如Internet Explorer,来向IIS.Apache等Web服务器发送HTTP ...

  10. WCF服务全局异常处理机制

    服务端增加WCF服务全局异常处理机制,任一WCF服务或接口方式出现异常,将统一调用WCF_ExceptionHandler.ProvideFault方法,因此不需要每个方法使用try catch写法. ...