• 分布式任务队列 Celery —— 应用基础


    目录

    前文列表

    分布式任务队列 Celery
    分布式任务队列 Celery —— 详解工作流

    前言

    紧接前文,继续看 Celery 应用基础,下列样例依旧从前文 proj 中进行修改。

    Celery 的周期(定时)任务

    Celery 周期任务功能由 Beat 任务调度器模块支撑,Beat 是一个服务进程,负责周期性启动 beat_schedule 中定义的任务。
    e.g.

    # filename: app_factory.py
    from __future__ import absolute_import
    from celery import Celery
    from kombu import Queue, Exchange
    
    
    def make_app():
        app = Celery('proj')
        app.config_from_object('proj.celeryconfig')
    
        default_exchange = Exchange('default', type='direct')
        web_exchange = Exchange('task', type='direct')
        app.conf.task_default_queue = 'default'
        app.conf.task_default_exchange = 'default'
        app.conf.task_default_routing_key = 'default'
    
        app.conf.task_queues = (
            Queue('default', default_exchange, routing_key='default'),
            Queue('high_queue', web_exchange, routing_key='hign_task'),
            Queue('low_queue', web_exchange, routing_key='low_task'),
        )
    
        # 设定 Beat 时区,默认为 UTC 时区
        app.conf.timezone = 'Asia/Shanghai’
        # 在 beat_schedule 中声明周期任务
        app.conf.beat_schedule = {
            # 周期任务 Friendly Name
            'periodic_task_add': {
                # 任务全路径
                'task': 'proj.task.tasks.add’,
                # 周期时间
                'schedule': 3.0,
                # 指定任务所需的参数
                'args': (2, 2)
            },
        }
        return app

    使用 -B 选择,表示启动 Celery Worker 服务进程的同时启动 Beat 模块。

    这里写图片描述

    NOTE 1:Beat 会把周期任务的时间表存储在 celerybeat-schedule 文件,在执行指令的当前目录生成。当 timezone 发生改变时,Beat 会根据 celerybeat-schedule 的内容自动调整计时方式。

    NOTE 2:Beat 也支持 crontab 计时方式,十分简单易用。
    e.g.

    # filename: app_factory.py
    from celery.schedules import crontab
    
    …
        app.conf.beat_schedule = {
            'periodic_task_add': {
                'task': 'proj.task.tasks.add’,
                # 每隔一分钟周期执行
                'schedule': crontab(minute='*/1'),
                'args': (2, 2)
            },
        }

    Celery 的同步调用

    Task.get 方法处理用于获取任务的执行结果之外,还能够用于实现 Celery 同步调用,以满足更多的应用场景。
    e.g.

    # filename: tasks.py
    
    import time
    
    from proj.celery import app
    
    
    @app.task
    def add(x, y, debug=False):
        # Test sync invoke.
        time.sleep(10)
        for i in xrange(10):
            print("Warting: %s s" % i)
        if debug:
            print("x: %s; y: %s" % (x, y))
        return x + y

    同步调用任务 add

    >>> from proj.task.tasks import add
    >>> add.delay(2, 2).get()
    4

    这里写图片描述

    因为直接调用了 get 方法,所以进程会被阻塞知道任务 add 返回结果为止。

    Celery 结果储存

    如果你对任务执行的结果非常关注,那么你可以使用数据库(e.g. Redis)来充当 Backend,从而将执行结果持久化。
    e.g.

    # 执行一个任务,并取得任务 id
    >>> from proj.task.tasks import add
    >>> result = add.delay(2, 2)
    >>> result.status
    u’SUCCESS'
    >>> result.get()
    4
    >>> result.id
    '65cee5e0-5f4f-4d2b-b52f-6904e7f2b6ab’

    进入 Redis 数据库,查看该任务对应的记录。

    root@aju-test-env:~# redis-cli
    127.0.0.1:6379>
    
    # 查看 Redis 所有的 keys
    127.0.0.1:6379> keys *
     1) "celery-task-meta-da3f6f3d-f977-4b39-a795-eaa89aca03ec"
     2) "celery-task-meta-38437d5c-ebd8-442c-8605-435a48853085”
    ...
    35) "celery-task-meta-65cee5e0-5f4f-4d2b-b52f-6904e7f2b6ab"
    ...
    
    # 通过任务 id,可以定位出任务在 Redis 中的 value
    127.0.0.1:6379> GET 'celery-task-meta-65cee5e0-5f4f-4d2b-b52f-6904e7f2b6ab'
    "{"status": "SUCCESS", "traceback": null, "result": 4, "task_id": "65cee5e0-5f4f-4d2b-b52f-6904e7f2b6ab", "children": []}"

    Celery 的监控

    Celery Flower 是 Celery 官方推荐的监控工具,借助于 Celery Events 接口,Flower 能够实时监控 Celery 的 Worker、Tasks、Broker、并发池等重要对象。

    • 安装 Flower
    $ pip install flower
    • 开启 Celery Events
    celery worker -A proj -E -l info

    这里写图片描述

    • 开启 RabbitMQ Management Plugin
    $ rabbitmq-plugins enable rabbitmq_management
    $ service rabbitmq-server restart
    • 启动 Flower,并指定 broker URL
    >nbsp;celery flower -l info --broker_api=http://guest:guest@<rabbitmq_server_ip>:15672/api/

    这里写图片描述

    • 访问 Flower Web,浏览器打开 http://<flower_server_ip>:5555/dashboard

    这里写图片描述

    Celery 的调试

    Celery 借助 telnet 可以支持远程 pdb 调试,非常方便。

    # filename: tasks.py
    from proj.celery import app
    from celery.contrib import rdb
    
    
    @app.task
    def add(x, y):
        # 设置断点
        rdb.set_trace()
        return x + y

    使用 celery.contrib 的 rdb 来设置断点,然后重启 Celery Worker 服务。

    这里写图片描述

    可以看见日志中提示了 telnet 远程连接的地址,所以打开另外一个终端,执行 telnet 指令即可完成连接,进入到非常熟悉的 pdb shell。

    这里写图片描述

  • 相关阅读:
    FetchApi 和XHR的主要区别
    关于面试mysql优化的几点纪要
    Python学习第二天数组
    windows7__32位下安装python2.6.6
    一致性哈希算法运用到分布式
    2019年的前端面试总结
    ant design vue + ts 时遇到的坑之from 表单
    vue/cli3 + typescript 中watch prop component computed 的用法
    简易的数据追踪和并发
    基于角色的安全体系
  • 原文地址:https://www.cnblogs.com/jmilkfan-fanguiju/p/10589780.html
Copyright © 2020-2023  润新知