【问题标题】:Celery + Python: Queue time consuming tasks within another taskCelery + Python:在另一个任务中排队耗时的任务
【发布时间】:2018-02-12 04:10:15
【问题描述】:

我想查询一个包含很多项目(~100)但不是一次全部的 api(这很耗时)。相反,我希望查询之间有一点延迟。

我目前拥有的是一个异步执行并遍历查询并在每次迭代后等待一段时间的任务:

@shared_task
def query_api_multiple(values):
    delay_between_queries = 1

    query_results = []

    for value in values:
        time.sleep(delay_between_queries)

        response = query_api(value)
        if response['result']:
            query_results.append(response)

    return query_results

我的问题是,当多个请求进来时,第二个请求会在第一个请求完成后执行还是在第一个请求仍在运行时执行?当它们没有同时被执行时,我该如何实现呢?

【问题讨论】:

  • 您应该使用 ETA – 为以后安排任务,使用 ETA(估计到达时间)异步执行该任务,例如: later = now + timedelta(hours=1) access_awful_system.apply_async((object_id) , eta=later) reference ETA。

标签: python celery django-celery


【解决方案1】:

你不应该使用time.sleep,而是限制你的任务:

Task.rate_limit

设置此任务类型的速率限制(限制 可以在给定时间范围内运行的任务数)。

可以通过以下方式以秒、分钟或小时为单位指定速率限制 将“/s”、“/m”或“/h”附加到值。任务将均匀 分布在指定的时间范围内。

示例:“100/m”(每分钟一百个任务)。这将强制执行最低 在同一个工作实例上启动两个任务之间的延迟为 600 毫秒。

因此,如果您想将其限制为每秒 1 个查询,请尝试以下操作:

@shared_task(rate_limit='1/s')
def query_api_multiple(values):
    ...

【讨论】:

  • 此速率限制仅适用于每个工作人员,要么他们要求您将此任务添加到队列中,然后只有 1 个工作进程排队,要么根本不添加速率限制,有没有更好的在所有工人都遵守速率限制的情况下处理此问题的方法
【解决方案2】:

是的,如果您创建多个任务,那么它们可能会同时运行。

如果您想限制每个时间段运行的任务数量,您可以使用 celery 对任务类型进行速率限制。或者,如果您需要比 celery 提供的 OOtB 更大的灵活性,您可以使用 redis 之类的东西结合 celery 重试来实现速率限制模式。

【讨论】:

    猜你喜欢
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2015-06-16
    相关资源
    最近更新 更多