zoukankan      html  css  js  c++  java
  • Python Flask后端异步处理(二)

      在实际的应用场景中,如用户注册,用户输入了注册信息后,后端保存信息到数据库中,然后跳转至登录界面,这些操作用户需要等待的时间非常短,但是如果是有耗时任务,比如对输入的网址进行漏洞扫描,在后端处理就会花费几分钟的时间,不可能让用户等待页面刷新几分钟,所以需要进行后端异步处理。之前使用的后端异步处理时Python的原生线程/进程实现,简洁暴力,自己用的话还行,但是如果是给用户用,就还存在一些不足,现考虑使用Celery替换掉原生线程/进程异步处理。

    Celery

      Celery是个Python语言实现的异步分布式任务队列服务,除了支持即时任务,还支持定时任务,Celery有五个核心角色。

    • Task 任务

      任务(Task)就是你要做的事情,例如一个注册流程里面有很多任务,给用户发验证邮件就是一个任务,这种耗时的任务就可以交给Celery去处理,还有一种任务是定时任务,比如每天定时统计网站的注册人数,这个也可以交给Celery周期性的处理。

    • Broker 经纪人,队列,消息传递者

      Broker 的中文意思是经纪人,指为市场上买卖双方提供中介服务的人。在Celery中这个角色相当于数据结构中的队列,介于生产者和消费者之间经纪人。例如一个Web系统中,生产者是主程序,它生产任务,将任务发送给 Broker,消费者是 Worker,是专门用于执行任务的后台服务。Celery本身不提供队列服务,一般用Redis或者RabbitMQ来实现队列服务。

    • Worker 执行者,消费者

      Worker 就是那个一直在后台执行任务的人,也成为任务的消费者,它会实时地监控队列中有没有任务,如果有就立即取出来执行。

    • Beat 定时任务调度器

      Beat 是一个定时任务调度器,它会根据配置定时将任务发送给 Broker,等待 Worker 来消费。

    • Backend 执行结果

      Backend 用于保存任务的执行结果,每个任务都有返回值,比如发送邮件的服务会告诉我们有没有发送成功,这个结果就是存在Backend中,当然我们并不总是要关心任务的执行结果。

    celery.png

      接下来编写一个简单的python程序来学习使用Celery

      首先是安装Celery,因为我的开发平台是Windows,Celery新版是不支持Windows操作系统的,需要下载老版本的,这里参考github上Celery开发者的回答:  https://github.com/celery/celery/issues/4178

      下载3.1.24版本的Celery

    pip3 install celery==3.1.24

      此外还要下载Reids,并且启动Redis的服务,此处百度

    创建Celery实例

    # task.py
    from celery import Celery
    ​
    app = Celery('task', broker='redis://localhost:6379/0')

    创建任务

    #task.py
    @app.task
    def send_mail(email):
        print("send mail to ", email)
        import time
        time.sleep(5)
        return "success"

      默认读者有flask基础,另外这里使用app.task 包装 send_email , 使其成为后台运行的任务

      函数使用app.task装饰器修饰之后,就会成为Celery中的一个Task。

    启动Worker

      启动Worker,监听Broker中是否有任务

    celery worker

      可以带参数如

    celery -A task worker --loglevel=info

      -A: 指定 celery 实例所在哪个模块中,--loglevel:显示日志等级

      运行后如下

    bug5.png

    调用任务

      在主程序中调用任务,调任务发送给Broker,跟开一个多线程和多进程类似,相当于是把任务丢给了Broker,主程序继续向下执行。

    from task import send_mail
    ​
    def register():
        import time
        start = time.time()
        print("1. 插入记录到数据库")
        print("2. celery 帮我发邮件")
        send_mail.delay("xx@gmail.com")
        print("3. 告诉用户注册成功")
        print("耗时:%s 秒 " % (time.time() - start))
    ​
    if __name__ == '__main__':
        register()

      因为send_mail被app.task装饰器修饰了,所以我们想要把任务丢给它,使用函数的 .delay方法即可

      目录结构为:

    ── Celery测试
       ├── task.py
       └── user.py

      运行user.py,查看运行结果为:

    bug6.png

      可知

    time.sleep(5)

      被丢到后台去执行了,所以花费时间这么短。如果按照正常的同步逻辑去实现,至少需要5秒钟的时间,因为存在time.sleep(5)来模拟发送邮件。

      在worker服务窗口查看日志信息

    bug7.png

      跟着大佬们的博客学习了Celery的基本操作,大部分时间去安装环境了,淦

      将Celery添加进碎遮项目会在下一篇博客中说到。

      请听下回分解 咕咕咕

    安装出现的错误

    File "d:python3libsite-packagesceleryconcurrencyprefork.py", line 20, in <module> from celery.concurrency.base import BasePool File "d:python3libsite-packagesceleryconcurrencyase.py", line 21, in <module> from celery.utils import timer2 File "d:python3libsite-packagesceleryutils imer2.py", line 19 from kombu.async.timer import Entry, Timer as Schedule, to_timestamp, logger ^ SyntaxError: invalid syntax

    bug1.png

      参考自:https://www.cnblogs.com/zivli/p/11517797.html

      这个是python3.7目前不支持kombu,降低python版本至3.6即可,(又得重新装一波python,没装conda呜呜呜,卸载之前先把python的类库输出到requirements.txt文件

      关于卸载python,可以参考这篇博客:https://blog.csdn.net/ke_yi_/article/details/88183474

      如果电脑上是python2和python3共存,请看:https://blog.csdn.net/autista/article/details/73650943

      弄好了之后再把之前python3.7的库文件恢复到python3.6里面来

    pip3 install -r requirements.txt

      弄好了之后重新打开python的集成开发环境

    celery -A task worker --loglevel=info

    bug2.png

      可算能运行Celery了

      接着运行程序的时候又遇到了

    AttributeError: 'str' object has no attribute 'items'

    bug3.png

      出现该问题的原因是redis版本过高,降低redis版本即可

    pip3 install redis==2.10.6

      然后就没有遇到其他的坑了,遇到再补:D

    参考链接

     

  • 相关阅读:
    高精度计算
    高精度除以低精度
    P1258 小车问题
    POJ 2352 stars (树状数组入门经典!!!)
    HDU 3635 Dragon Balls(超级经典的带权并查集!!!新手入门)
    HDU 3938 Portal (离线并查集,此题思路很强!!!,得到所谓的距离很巧妙)
    POJ 1703 Find them, Catch them(确定元素归属集合的并查集)
    HDU Virtual Friends(超级经典的带权并查集)
    HDU 3047 Zjnu Stadium(带权并查集,难想到)
    HDU 3038 How Many Answers Are Wrong(带权并查集,真的很难想到是个并查集!!!)
  • 原文地址:https://www.cnblogs.com/Cl0ud/p/13192925.html
Copyright © 2011-2022 走看看