Cron в распределённой системе

Cron-задания часто являются одной из составляющих долгоживущего сервиса.

Могут применяться как сборщики мусора. Или как инициаторы заданий для воркеров.

Проблематика

В большой распределённой системе cron-задания могут быть не рассчитаны на параллельную работу. Например, не реализовывать протокол Paxos

Поэтому требуется реализовать блокировку от параллельного выполнения.

Но начнём мы с часто совершаемой ошибки при полном цикле разработки и эксплуатации в разных отделах

cron находится в отличном от кода репо / настраивается вручную по заявке

Предположу, что есть варианты, когда срок горит, а разбираться в CI/DevOps практиках лень.

Тогда долгосрочной эксплуатации продукта отдаётся меньший приоритет, чем быстрому запуску.

Как следствие - cron настраивается инженерами экплуатации в системе, к которой программистам доступа нет.

Для грамотной разработки и поддержки важно понимать, как работает проект сейчас (в общем случае в конкретный момент времени).

А так как cron - часть проекта, его работа должна быть понятной для всех (разработчиков, эксплуатации и т.д.).

Поэтому вывод

Cron должен быть реализован в проекте

Основные агурменты за:

  • конфигурация на виду у всех членов команды, а не записана в блокноте у уволенного сотрудника;
  • имеется возможность протестировать и внести изменения вместе с изменениями проекта;

Реализация

Обычно вызов cron операций бывает:

  1. асинхронным вызовом через сеть (веб-сервер или другой сигнал для запуска команды);
  • этот путь не даёт контроля над результатом выполнения cron-операции;
  • возможен, если это постановка задания в очередь, а не выполнение самого задания.
  • можно воспользоваться готовым образом https://hub.docker.com/r/renskiy/cron/
  1. вызовом операции в самом приложении
  • контроль исполнения;
  • контроль ресурсов;
  • получаем точный код и трассировку в случае ошибки.

Ограничения

В распределённой системе нужно котролировать параллельный запуск, если возможны ошибки при параллельном выполнении двух cron-заданий.

Блокировка от параллельного выполнения

#!/bin/bash
PROCNUM=`ps xa | grep -v grep | grep -c "/srv/www/data/cron.php"`
# если процесс уже есть - выходим
if [ $PROCNUM -gt 0 ]; then exit; fi

/usr/local/bin/php /srv/www/data/cron.php

Обработка ошибок

Сообщения, которые затем должны быть видны в системе логирования, стоит записать в лог контейнера. Система логирования автоматически их обработает и отдаст в удобном для клиента виде.

Соответствует методике 12 факторов