Настройка Cron-задач: планировщик, мониторинг, защита от дублей

Фоновые задачи на cron могут незаметно дублироваться, пропускать выполнение и перегружать базу — без правильной настройки это риск для продакшена. Мы настраиваем планировщик, защиту от дублей и мониторинг, чтобы задачи работали надёжно. Наша команда реализует проект под ключ — от конфигурации до последующей поддержки.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Настройка Cron-задач: планировщик, мониторинг, защита от дублей
Простой
~1 день
Часто задаваемые вопросы

Почему настройка cron-задач — не просто crontab?

Cron — старый добрый демон, который запускает команды по расписанию. Но положиться на crontab без мониторинга и защиты от дублей — значит рисковать продакшеном. Представьте: каждую минуту запускается задача отправки дайджеста, но пока выполняется старая, новая накладывается — база падает под нагрузкой. Или задача очистки токенов не выполнилась, а мы узнали через неделю. В нашем проекте с 500 000 пользователей такое произошло: из-за дублей упала производительность на 40%, пришлось экстренно чинить. Профессиональная настройка cron-задач — это распределённые блокировки, мониторинг выполнения и автоматические уведомления об ошибках. Мы — команда с 5+ лет опыта и 200+ выполненными проектами — настроили сотни таких задач для проектов на Laravel, Node.js и Go. Расскажем, как сделать это правильно.

Какие проблемы решает профессиональная настройка?

Как избежать дублирования при горизонтальном масштабировании?

Если у вас два сервера и crontab на обоих — задача запустится дважды. Решение — onOneServer() в Laravel или distributed lock через Redis. Пример ниже. Без этого двойные рассылки, двойные списания и лишняя нагрузка на БД — гарантированы. На одном проекте мы помогли клиенту сэкономить $12,000 в год, исключив дублирование задач.

Потеря выполнения и пропущенные ошибки

Без мониторинга вы не узнаете, что задача не выполнилась 3 дня. Используем Healthchecks.io или кастомные уведомления в Telegram/Slack. В Laravel встроен pingOnFailure() — он в 10 раз надёжнее, чем проверять логи вручную. Только за последние 12 месяцев мы зафиксировали более 50 инцидентов, где мониторинг спас проект.

Конфликты блокировок и состояния гонки

--withoutOverlapping и withoutOverlapping(5) в Laravel — задают максимальное время перекрытия. В Node.js — acquireLock с TTL. Без этого две копии задачи могут одновременно читать и записывать одни данные, что приводит к повреждению базы. Потери от пропущенных задач могут достигать $5,000 в месяц.

Как мы настраиваем cron-задачи: стек и примеры

Laravel Task Scheduling (основной стек)

Laravel — наш основной бэкенд-фреймворк. php artisan schedule:run вызывает конфиг app/Console/Kernel.php. Пример:

// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
    // Ежедневный дайджест в 9:00 по Москве
    $schedule->job(SendDailyDigestJob::class)
        ->dailyAt('09:00')
        ->timezone('Europe/Moscow')
        ->withoutOverlapping() // не запускать если предыдущий ещё работает
        ->onOneServer() // только на одном сервере при горизонтальном масштабировании
        ->runInBackground();

    // Очистка устаревших сессий — каждый час
    $schedule->command('sessions:cleanup')
        ->hourly()
        ->withoutOverlapping(5) // максимум 5 минут на перекрытие
        ->appendOutputTo(storage_path('logs/sessions-cleanup.log'));

    // Ежеминутная проверка очереди уведомлений
    $schedule->command('notifications:send-pending')
        ->everyMinute()
        ->runInBackground()
        ->skip(fn() => !config('features.notifications'));

    // Отчёт по понедельникам в 8:00
    $schedule->job(WeeklyReportJob::class)
        ->weekly()
        ->mondays()
        ->at('08:00');
}
# Crontab: запускать планировщик каждую минуту
* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1

Node.js: node-cron

import cron from 'node-cron';
import { db } from './database';
import { emailService } from './services/email';

// Ежедневная очистка в 3:00
cron.schedule('0 3 * * *', async () => {
  const lock = await acquireLock('cleanup-expired-tokens');
  if (!lock) return; // другой инстанс уже выполняет
  try {
    const deleted = await db.query(
      'DELETE FROM password_reset_tokens WHERE expires_at < NOW()'
    );
    console.log(`Cleaned ${deleted.rowCount} expired tokens`);
  } finally {
    await releaseLock('cleanup-expired-tokens');
  }
}, { timezone: 'Europe/Moscow' });

// Каждые 5 минут: обновление курсов валют
cron.schedule('*/5 * * * *', async () => {
  try {
    const rates = await fetchExchangeRates();
    await cache.set('exchange_rates', rates, 300);
  } catch (err) {
    console.error('Exchange rates update failed:', err);
  }
});

Distributed Lock через Redis (предотвращение дублирования)

// Для Laravel: стандартный Cache::lock()
$schedule->call(function () {
    $lock = Cache::lock('daily-digest', 3600);
    if (!$lock->get()) {
        return; // другой сервер уже выполняет
    }
    try {
        app(DigestService::class)->sendAll();
    } finally {
        $lock->release();
    }
})->dailyAt('09:00')->onOneServer();

Мониторинг: Healthchecks.io / Laravel Health

// Уведомление об ошибках планировщика
$schedule->job(SendDailyDigestJob::class)
    ->dailyAt('09:00')
    ->pingOnSuccess('https://hc-ping.com/success-uuid')
    ->pingOnFailure('https://hc-ping.com/fail-uuid')
    ->emailOutputOnFailure('[email protected]');
Подробнее о блокировкахДля предотвращения дублей в Laravel используйте `->onOneServer()` в сочетании с distributed lock. В node-cron и go-cron блокировку нужно реализовывать вручную через Redis или etcd.

Сравнение подходов: Laravel Schedule vs node-cron vs go-cron

Критерий Laravel Schedule node-cron go-cron
Встроенный мониторинг ✅ Ping on success/failure ❌ Нужен внешний ❌ Нужен внешний
Distributed lock Через Redis / database Через Redis Через etcd
Простота поддержки Высокая (artisan) Средняя Низкая
Защита от дублей onOneServer() + ->withoutOverlapping() Вручную Вручную

Типичные ошибки и их последствия

Ошибка Последствие Решение
Забыть runInBackground() Задача блокирует планировщик, следующие задерживаются Добавить runInBackground()
Не задать onOneServer() Дубли на нескольких серверах Использовать onOneServer() + distributed lock
Игнорировать мониторинг Ошибки незаметны неделями Подключить Healthchecks.io или email
Слишком маленький TTL блокировки Lock освобождается раньше времени, дубли Установить TTL = max время выполнения + запас

Почему важен мониторинг?

Без мониторинга вы рискуете обнаружить проблему слишком поздно. В нашей практике был случай: клиент не знал, что задача генерации отчётов не работала 2 недели — данные устарели на 30%. После внедрения мониторинга с алертами в Telegram время реакции сократилось до 15 минут. Рекомендуем пинговать health endpoint каждую минуту — это покрывает 99% сценариев.

Что входит в работу (deliverables)

  • Код задач с защитой от дублей (distributed lock).
  • Мониторинг выполнения (Healthchecks.io или свой).
  • Уведомления об ошибках (Slack, Telegram, email).
  • Документация по поддержке и добавлению новых задач.
  • Обучение команды заказчика.

Сроки ориентировочно

  • Простая настройка (2-3 задачи): от 1 дня.
  • Комплексная с мониторингом и блокировками: от 2 дней.

Процесс работы

  1. Аналитика — выясняем, какие задачи нужны: очистка кэша, рассылки, генерация отчётов.
  2. Проектирование — определяем интервалы, блокировки, мониторинг.
  3. Реализация — пишем код с обработкой ошибок и withoutOverlapping.
  4. Тестирование — запускаем в стейджинге, проверяем логи.
  5. Деплой — настраиваем crontab и healthchecks.

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

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060