Sobes.tech
Back to questions
Middle
1

Есть 5 инстансов сервиса с кронзадачей. Как сделать так, чтобы задача выполнилась только один раз, а не 5 раз?

Companies where asked
Бюро 1440Бюро 1440

Answer from AI

sobes.tech AI

Чтобы задача срабатывала только один раз среди 5 инстансов, нужно реализовать механизм распределённой блокировки или лидерства. Один из распространённых подходов — использовать внешнее хранилище с поддержкой атомарных операций, например Redis или базу данных.

Пример с Redis и Python:

import redis
import time

redis_client = redis.Redis()
lock_key = "cron_task_lock"
lock_timeout = 60  # время жизни блокировки в секундах

# Попытка установить блокировку
if redis_client.set(lock_key, "locked", nx=True, ex=lock_timeout):
    try:
        # Выполнение задачи
        print("Задача выполняется одним инстансом")
        # ... код задачи ...
    finally:
        redis_client.delete(lock_key)
else:
    print("Другой инстанс уже выполняет задачу")

Здесь set с параметром nx=True устанавливает ключ только если его нет, что гарантирует, что только один инстанс получит блокировку. ex задаёт время жизни ключа, чтобы избежать вечной блокировки при сбое.

Альтернативы:

  • Использовать распределённые системы координации, например ZooKeeper или etcd.
  • Использовать специализированные библиотеки для распределённых задач (например, Celery с брокером сообщений).

Таким образом, задача запускается только одним инстансом, остальные пропускают выполнение.