Сценарий

Пайплайны по расписанию рядом с вашими API

Запускайте serverless cron-задачи как пайплайны по расписанию: история запусков рядом с HTTP-вызовами, настраиваемые ретраи, общие секреты и логи — ночная работа использует те же функции, что и ваши REST-эндпоинты.

Обновлено: 2026-06-28

Суть ответа

Пайплайны по расписанию рядом с вашими API. Один и тот же ID функции может обслуживать HTTP-маршрут и шаг пайплайна по расписанию — без дублирования деревьев кода.

Когда подходит

  • Ночной ETL
  • Ротация сертификатов или токенов
  • Периодический опрос интеграций

На что обратить внимание

  • Таймеры повышают надёжность срабатывания, но не дают изоляции зависимостей и общих секретов и логов, которыми уже пользуются ваши HTTP-обработчики.
  • Всё равно нужно одно место для ретраев, истории запусков и алертов — иначе задачи по расписанию остаются невидимыми рядом с продакшен-API.

Почему hosted cron и crontab подводят

  • Crontab на VPS: вывод уходит в почту root; встроенных ретраев нет
  • systemd timers: надёжное срабатывание, но разрозненные логи и секреты вручную
  • Kubernetes CronJob: надёжные примитивы, но накладные расходы кластера для маленьких команд

Cron-задачи падают тихо, когда их единственный вывод уходит в почту root или в случайные лог-файлы, которые никто не читает.

Если расписания живут только на VPS, на вас расхождение окружений, расползание секретов и отладка в духе «кто перезапускал cron?» — каждый инцидент превращается в археологию по SSH.

Записи crontab живут вне версионируемого пайплайна деплоя, и никто не знает, какой бинарник запускался прошлой ночью.

Перекрывающиеся запуски портят общее состояние, если нет защиты skip-if-running, — пайплайнам по расписанию нужна та же строгость, что и обработчикам вебхуков.

Почему одних таймеров недостаточно

Таймеры повышают надёжность срабатывания, но не дают изоляции зависимостей и общих секретов и логов, которыми уже пользуются ваши HTTP-обработчики.

Всё равно нужно одно место для ретраев, истории запусков и алертов — иначе задачи по расписанию остаются невидимыми рядом с продакшен-API.

Одна платформа для API и расписаний

Один и тот же ID функции может обслуживать HTTP-маршрут и шаг пайплайна по расписанию — без дублирования деревьев кода.

Cron-выражения проверяются при сохранении пайплайна; воркер хранит nextRunAt для каждого пайплайна, поэтому правки перепланируются аккуратно, а история запусков остаётся доступной для запросов.

crontab, systemd timers, Kubernetes CronJob и Inquir

Выбор планировщика зависит от зрелости эксплуатации и того, где уже живёт остальной стек. Таблица сравнивает четыре типичных подхода к повторяющейся бэкенд-работе — не edge-cron и не субсекундные тики.

crontab, systemd timers, Kubernetes CronJob и Inquir
Критерийcrontabsystemd timersKubernetes CronJobПайплайны Inquir по расписанию
Настройка и сопровождениеПравка crontab на хосте; выражение не проверяется при сохраненииUnit- и timer-файлы; надёжнее срабатывание, но упаковка всё ещё на уровне хостаYAML-манифесты и работающий кластер — даже для одной ночной задачиCron на триггере пайплайна; выражение проверяется при сохранении
История запусковПеренаправление stdout в файл или почту root — без структурированного аудитаjournalctl по unit; при росте числа задач — grep по сервисамЛоги подов и статус Job; хранение зависит от стека логирования кластераЗаписи вызовов рядом с HTTP-выполнениями — доступны без SSH
Ретраи при сбоеНет — следующее срабатывание и есть единственный неявный ретрайOnFailure= может перезапустить unit; политики ретраев на запуск в продуктовом UI нетbackoffLimit у Job; настраивается в манифесте, не рядом с историей APIЧисло ретраев и задержка на каждом шаге пайплайна
Секреты.env на сервере или inline в shell — общие для всех задач на хостеEnvironmentFile в unit; ротация по-прежнему вручную на каждом хостеKubernetes Secrets — нативно для кластера, но отдельно от авторизации на шлюзе приложенияСекреты воркспейса, общие с HTTP-маршрутами — без параллельного .env на сервере
Изоляция между задачамиОдин UNIX-пользователь и окружение интерпретатора — конфликты зависимостей типичныМожно запускать от разных пользователей; всё равно одна машина, общее ядроПод на запуск — сильная изоляция, когда кластер уже оправданКонтейнер на вызов — та же модель изоляции, что у синхронных HTTP-обработчиков
Версионирование вместе с кодомСтроки crontab часто живут вне пайплайна деплояUnit-файлы могут лежать в git; расхождение между хостами всё равно случаетсяМанифесты в git/GitOps — отлично, когда K8s уже control planeБандлы функций и конфиг пайплайна версионируются вместе с деплоем платформы
Многошаговые воркфлоуShell-скрипты с цепочкой команд — непрозрачные точки сбояОтдельные unit или bash в ExecStart — ручная оркестрацияОдин контейнер на CronJob; для DAG нужны Argo/Workflows или аналогиГрафы пайплайнов с рёбрами — extract, transform, load как узлы-функции
Перекрытие / долгие прогоныРучной flock или надежда — параллельные запуски портят общее состояниеНастройки concurrency на unit — логику всё равно пишете сами в обработчикеconcurrencyPolicy Forbid/Replace в спецификации CronJobЗащита skip-if-running и ключи идемпотентности в обработчике или в дизайне пайплайна
Когда уместноОдна VPS, один инженер, скрипты уже работают и редко падаютLinux-команды эксплуатации на systemd, готовые копать journalПродукт уже на Kubernetes с GitOps и логированием кластераПайплайны по расписанию и REST на одной платформе — история и ретраи без YAML кластера

Расписание, ретраи и наблюдаемость

Проверка cron

Выражения расписания проверяются при сохранении, поэтому некорректные записи отсекаются сразу.

Шаг воркера и перекрытия

Проектируйте нагрузку минутного масштаба и добавляйте защиту skip-if-running для долгих задач.

История выполнений

Ответ на вопрос «задача отработала?» без grep — история запусков лежит рядом с HTTP-вызовами.

Алерты по запускам

Подключите мониторинг к доле ошибок или SLO по длительности для задач по расписанию.

Чеклист миграции

Безопасно перенесите одну повторяющуюся задачу из shell в пайплайн по расписанию.

1

Вынести обработчик из shell-скрипта

Перенесите логику скрипта в версионируемую функцию.

2

Проверить функцию и задать расписание пайплайна

Сначала проверьте вывод функции. В визуальном редакторе пайплайнов соедините узел cronTrigger с этой функцией и сохраните расписание.

3

Добавить защиту от перекрытий и алерт

Не дайте параллельным запускам портить данные и показывайте сбои сразу.

Типовые паттерны cron-задач

Обработчики по расписанию получают метаданные пайплайна в event. Два типовых паттерна: инкрементальная синхронизация с курсором-отметкой (безопасно ретраить) и генерация отчёта с веерной рассылкой.

jobs/incremental-sync.mjs (паттерн с курсором-отметкой)
export async function handler(event) {
  // Read cursor from env so re-runs do not re-process old records
  const since = process.env.SYNC_CURSOR ?? new Date(Date.now() - 86_400_000).toISOString();
  const records = await source.fetchUpdatedSince(since);
  await destination.upsertBatch(records); // idempotent by record ID
  const newCursor = records.at(-1)?.updatedAt ?? since;
  // Update cursor in your config/store for next run
  return { synced: records.length, cursor: newCursor };
}
jobs/nightly-report.mjs (отчёт + веерная рассылка)
export async function handler(event) {
  const rows = await buildReport();
  await storage.upload(rows, { key: `reports/${new Date().toISOString().slice(0, 10)}.csv` });
  // Fan out — each recipient gets a separate pipeline step
  await Promise.all(
    recipients.map((r) => global.durable.startNew('send-report', undefined, { recipientId: r.id, rowCount: rows.length })),
  );
  return { rows: rows.length, notified: recipients.length };
}

Выбирайте этот сценарий, когда…

Когда это уместно

  • Ночной ETL
  • Ротация сертификатов или токенов
  • Периодический опрос интеграций

Когда лучше выбрать другое

  • Субсекундные периодические задачи — сначала проверьте таймеры платформы

Частые вопросы

Что если запуск cron длится дольше интервала?

Используйте ключи идемпотентности, распределённые локи или защиту skip-if-running внутри обработчика, чтобы перекрывающиеся запуски не портили общее состояние.

Чем это лучше crontab на одной машине?

Вы получаете версионируемые бандлы функций, изоляцию контейнера на каждый вызов, сохранённые записи вызовов и ту же модель секретов, что у HTTP-функций, — плюс многошаговые графы, когда одно расписание должно разветвляться.

Какой часовой пояс у cron-выражений?

Зафиксируйте часовой пояс, который ожидает команда (для бэкендов часто UTC), и учитывайте переход на летнее время, если расписание привязано к бизнес-часам.