每20秒运行一次芹菜任务是重叠的,在最后一次任务完成之前就开始了

2022-12-05 02:09:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个芹菜任务,每20秒运行3个实例,所有实例都连接到一个数据库。问题是处理程序启动了两次,有时任务重叠。在任务重叠时,筛选的项目似乎没有更新:

@periodic_task(run_every=timedelta(seconds=20))
def process_webhook_transactions():
    """Process webhook transactions"""
    transactions = WebhookTransaction.objects.filter(status=WebhookTransaction.UNPROCESSED)
    for transaction in transactions:
        data = transaction.body
        event = data.get('event_category')
        if event is None:
            transaction.status = WebhookTransaction.ERROR
            transaction.save()
            continue
        
        
        handler = WEBHOOK_HANDLERS.get(event, default_handler)
        success = handler(data)

        if success:
            transaction.status = WebhookTransaction.PROCESSED
        else:
            transaction.status = WebhookTransaction.ERROR
        transaction.save()

避免这种情况的最佳方法是什么


Tags: 实例eventdatagetifsavestatuserrorwebhookhandler芹菜successtransactiontransactionswebhooktransaction
1条回答
网友
1楼 · 发布于 2022-12-05 02:09:36

您可以使用select_for_updateskip_locked来防止3个工人同时运行该任务时出现重复的行。像这样:

transactions = WebhookTransaction.objects.filter(status=WebhookTransaction.UNPROCESSED)
transactions = transactions.select_for_update(skip_locked=True, of=("self",))

但这种方法将使一个工作实例比其他实例更难工作(第一个任务选择了所有事务,而其他实例没有多少事务剩余)。您可以创建一个在20秒内运行的新任务,该任务将把所有事务分割成更小的块(可能是10-20?),然后用这些块触发process_webhook_transactions

如果handler = WEBHOOK_HANDLERS.get(event, default_handler)是异步的,我认为分割块方法也很好,因为您可以并发运行它来提高任务的速度