zoukankan      html  css  js  c++  java
  • python之celery异步处理

      在写个人博客项目的时候,涉及到邮件验证码和短信验证码的发送的功能,应该异步地去执行,而不是同步形成阻塞。这时就要用到python的扩展库celery。

      celery是一个强大的分布式任务队列的异步处理组件,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。

      Celery的架构由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。

    消息中间件:

      Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等

    任务执行单元:

      Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。

    任务结果存储:

      Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等

      个人理解,有些功能,比如发短信通知,是一个耗时任务,如果都扎堆在一起去执行,同步操作一次执行一个,一次发一条短信,势必会形成阻塞。例如美团外卖,中午12点整的下单人数100个,每个人下单完成后系统都要发个短信给用户说“下单成功”,每次发短信时间假如是1s,那就要100s发完这100条短信,那第101个人下单完成后要等100秒才能收到短信,这是什么用户体验?很显然,我们不能一次发一条短信,而应该并发,一次发N条。这些并发技术是比较底层的,写起来很麻烦,而celery就帮我们封装好了这些并发技术,我们要做的就是通过celery去调动执行并发。

    使用场景:

      异步任务:将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等等

      定时任务:定时执行某件事情,比如每天数据统计

    之前在cms后台修改邮箱的时候点击发送验证码邮件,会有大概1.2s的延时然后弹出发送成功的对话框。这个延时就是调用flask扩展mail发送邮件的耗时,这时在同步场景下执行的。现在换成celery的异步操作:

     1 from celery import Celery
     2 from flask_mail import Message
     3 from exts import mail
     4 from flask import Flask
     5 import config
     6 app = Flask(__name__)
     7 app.config.from_object(config)
     8 mail.init_app(app) # 初始化app
     9 
    10 def make_celery(app):
    11     celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],broker=app.config['CELERY_BROKER_URL'])
    12     celery.conf.update(app.config)
    13     TaskBase = celery.Task
    14     class ContextTask(TaskBase):
    15         abstract = True
    16         def __call__(self, *args, **kwargs):
    17             with app.app_context():
    18                 return TaskBase.__call__(self, *args, **kwargs)
    19     celery.Task = ContextTask
    20     return celery
    21 
    22 celery = make_celery(app)
    23 
    24 @celery.task
    25 def send_mail(subject,recipients,body):
    26     message = Message(subject=subject,recipients=recipients,body=body)
    27     mail.send(message)

    之后点击发送验证码就是立即弹出alert了。用户体验极佳。

    这里要注意,目前我这个项目运行在window10上,但是celery对windows不太友好,4.x版本后不支持windows,要用eventlet去解决。eventlet是Python的并发网络库。

    在命令行开启:celery -A tasks.celery worker --pool=eventlet --loglevel=info

    后来发现一定几率出现莫名的报错。

    将eventlet改为solo就可以了:

    celery -A tasks.celery worker --pool=solo --loglevel=info

     

  • 相关阅读:
    如何将baidu地图中的baidu logo 去掉
    漂亮的圆角文本框 CSS3实现
    jQuery数字加减插件
    腾迅股票数据接口 http/javascript
    JS复制内容到剪贴板(兼容FF/Chrome/Safari所有浏览器)
    关于编写性能高效的javascript事件的技术
    想做web开发 就学JavaScript
    git的简单理解及基础操作命令
    《CSS权威指南》基础复习+查漏补缺
    TypeScript Writing .d.ts files(编写声明文件)
  • 原文地址:https://www.cnblogs.com/wangyi0419/p/13132394.html
Copyright © 2011-2022 走看看