Налаштування 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'));
}
# 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
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060