• celery任务队列使用


    celery任务队列使用

    • 项目架构

      .
      ├── broker
      │   ├── __init__.py
      │   ├── cron.py
      │   └── req.py
      ├── config
      │   ├── __init__.py
      │   ├── dev.py
      │   └── prod.py
      ├── task
      │   ├── __init__.py
      │   ├── base.py
      │   ├── cron
      │   │   ├── __init__.py
      │   │   └── check.py
      │   └── req
      │       ├── __init__.py
      │       └── waste_task.py
      ├── main.py
      └── requirements.txt
      
    • 依赖包

      amqp               2.6.1
      billiard           3.6.4.0
      celery             4.4.0
      certifi            2021.10.8
      charset-normalizer 2.0.7
      idna               3.3
      importlib-metadata 4.8.2
      kombu              4.6.11
      pip                21.2.4
      pytz               2021.3
      redis              3.5.3
      requests           2.26.0
      setuptools         58.2.0
      typing-extensions  3.10.0.2
      urllib3            1.26.7
      vine               1.3.0
      wheel              0.37.0
      zipp               3.6.0
      
    • 配置

      # -*- coding=utf-8 -*-
      
      # 文件所在位置 : config/dev.py
      
      from datetime import timedelta
      # 公共配置
      COMMON_CONFIG = {
          "CELERYD_CONCURRENCY": 2,
          "CELERYD_MAX_TASKS_PER_CHILD": 10,
          "CELERYD_HIJACK_ROOT_LOGGER": True,
          "CELERY_ANNOTATIONS": {
              '*': {'rate_limit': '10/s'}
          }
      }
      
      # 任务队列配置
      REQ_CONFIG = {
          "BROKER_URL": 'redis://:123456@127.0.0.1:6379/1',
          "RESULTS_BACKEND ": 'redis://:123456@127.0.0.1:6379/2',
          "CELERY_IMPORTS": [
              'task.req.waste_task',
          ]
      }
      
      # 定时配置(定义简单版)
      CRON_CONFIG = {
          "BROKER_URL": 'redis://:123456@127.0.0.1:6379/3',
          "CELERY_DEFAULT_QUEUE": "default",
          "CELERY_IMPORTS": [
              'task.cron.check'
          ],
          'CELERYBEAT_SCHEDULE': {
              'check_product': {
                  'task': 'task.cron.check.test_1',
                  'schedule': timedelta(seconds=6), # 每6s执行一次
                  'args': () # 执行参数
              },
              'test_2': {
                  'task': 'task.cron.check.test_2',
                  'schedule': timedelta(seconds=10), # 每10s执行一次
                  'args': () # 执行参数
              },
              'test_3': {
                  'task': 'task.cron.check.test_3',
                  'schedule': timedelta(seconds=20), # 每20s执行一次
                  'args': () # 执行参数
              }
          }
      }
      
      # 定义请求任务队列配置和定时任务队列
      REQ_CONFIG.update(COMMON_CONFIG)
      CRON_CONFIG.update(COMMON_CONFIG)
      
    • 自定义任务基类

      # -*- coding=utf-8 -*-
      
      # 文件所在位置 : task/base.py
      
      from celery import Task
      
      # 任务基类
      class BaseTask(Task):
          # 成功时回调,只能证明此任务执行成功,不代表程序逻辑一定成功
          def on_success(self, retval, task_id, args, kwargs):
              print("任务成功")
              return super(BaseTask, self).on_success(retval, task_id, args, kwargs)
      
          # 失败回调, 当重试结束后或者直接失败,则会触发此方法
          def on_failure(self, exc, task_id, args, kwargs, einfo):
              print("任务失败")
              return super(BaseTask, self).on_failure(exc, task_id, args, kwargs, einfo)
      
          # 任务重试, 到最后一次重试后会走到失败回调,前端需要使用 self.retry() 方法触发
          def on_retry(self, exc, task_id, args, kwargs, einfo):
              print("重试")
              print(args)
              print(kwargs)
              super(BaseTask, self).on_retry(exc, task_id, args, kwargs, einfo)
      
          # 任务执行成功并返回内容,可以根据内容来判定是否是一次有效的执行任务
          def after_return(self, status, retval, task_id, args, kwargs, einfo):
              print(retval)
              super(BaseTask, self).after_return(status, retval, task_id, args, kwargs, einfo)
      
    • 代理人

      • 请求任务

        # -*- coding=utf-8 -*-
        
        # 文件所在位置 : broker/req.py
        
        from celery import Celery
        from config import REQ_CONFIG
        
        # 实例化任务队列
        req = Celery(
            "req" # 自定义队列名称
        )
        
        # 导入配置
        req.config_from_object(REQ_CONFIG)
        
      • 定时任务

        # -*- coding=utf-8 -*-
        
        # 文件所在位置 : broker/cron.py
        
        from celery import Celery
        from config import CRON_CONFIG
        cron = Celery(
            "cron" # 自定义实例名称
        )
        # 导入配置
        cron.config_from_object(CRON_CONFIG)
        
    • 任务

      • 请求任务

        # -*- coding=utf-8 -*-
        
        # 文件所在位置 : task/req.py
        
        from broker.req import req
        import requests
        from task.base import BaseTask
        
        
        @req.task(bind=True)
        def waste_task_1(self, x, y):
            return x * y
        
        @req.task(bind=True,base=BaseTask)
        def waste_task_2(self, id, url):
            try:
                resp = requests.get(url, timeout=2)
            except:
                self.retry(max_retries=3, countdown=5)
            return resp
        
      • 定时任务

        # -*- coding=utf-8 -*-
        
        # 文件所在位置 : task/cron.py
        
        from broker.cron import cron
        from task.base import BaseTask
        import time
        
        @cron.task(bind=True)
        def test_1(self):
            print("定时 test_1 : %s"%(time.time()))
        
        @cron.task(bind=True, base=BaseTask)
        def test_2(self):
            try:
                1 / 0
            except:
                self.retry(countdown=10, max_retries=5)
        
        @cron.task(bind=True, base=BaseTask)
        def test_3(self):
            try:
                print("定时 test_3 : %s"%(time.time()))
            except:
                self.retry(countdown=10, max_retries=5)
        
    • 启动任务

      • 启动请求任务

        celery -A broker.req worker --loglevel=info --logfile="xxx/req_task.log" &
        
      • 启动定时任务

        celery -A broker.cron beat
        celery -A broker.cron worker --loglevel=info --logfile="xxx/cron_task.log" &
        
    • 使用

      • 定时任务,已经自行启动并运行,所以不需要关注。

      • 请求任务,伪代码如下:

        # -*- coding=utf-8 -*-
        
        # 文件所在位置 : main.py
        
        from task.waste_task import waste_task_1, waste_task_2
        def test1():
            x, y = 10, 20
        	waste_task_1.delay(x, y)
        def test2():
            id, url = 100, "https://baidu.com"
            waste_task_2.delay(id, url)
        
  • 相关阅读:
    各大厂面试遇到的91道软件测试面试题+答案纯干货!!
    测试岗面试必看攻略
    自动化测试面试题及答案大全(1)
    自动化测试面试题及答案大全(2)
    自动化测试面试题及答案大全(3)
    自动化测试面试题及答案大全(4)
    自动化测试面试题及答案大全(5)
    Android反编译&Android安全测试
    ALV布局保存
    雨伞的主要材料有哪些?
  • 原文地址:https://www.cnblogs.com/wuxiaoshi/p/15528188.html
Copyright © 2020-2023  润新知